Algorithme de tri ---------- tri par tas

Tri de tas

introduction

Le tri de tas est aussi une sorte de sélection , la pire et la meilleure complexité en temps moyen est O (nlogn), qui est un tri instable

C'est un arbre binaire complet, la valeur de chaque nœud est supérieure ou égale à la valeur de ses nœuds enfants gauche et droit ===> grande poussée, notez qu'il ne nécessite pas la relation de taille entre les nœuds enfants gauche et droit , sinon c'est un petit tas supérieur

Idée basique

1. Construisez la séquence à trier dans un grand tas supérieur

À ce stade, la valeur maximale de la séquence entière est le nœud racine de l'élément de tas.

Échangez-le avec le dernier élément, et la fin est la valeur maximale à ce moment.

Ensuite, reconstruisez les n-1 éléments restants en une pile, de sorte que la prochaine plus petite valeur de n éléments soit obtenue. Une telle exécution répétée se traduira par une séquence ordonnée.

Diagramme

img

L'exemple de la vidéo d'instructions reçoit un tableau {4,6,8,5,9} utilisant l'algorithme de tri de tas

Insérez la description de l'image ici

Ensuite, nous partons du dernier nœud non-feuille (le nœud feuille n'a naturellement pas besoin d'être ajusté, le premier nœud non-feuille arr.length / 2-1 = 5 / 2-1 = 1, qui sont les 6 nœuds ci-dessous ), Ajustez de gauche à droite et de bas en haut .

Insérez la description de l'image ici

Ensuite, trouvez le deuxième nœud non-feuille 4, trouvez que 9 éléments de 4, 9, 8 sont les plus grands, et 4 et 9 sont échangés

Insérez la description de l'image ici

À ce moment, l'échange a rendu la structure de la sous-racine [4,5,6] chaotique et a continué à s'ajuster. Dans [4,5,6], 6 est le plus grand, et 4 et 6 sont échangés .

Insérez la description de l'image ici

Jusqu'à présent, notre grande poussée est terminée

Deuxième étape

Échangez l'élément supérieur avec le dernier élément pour que le dernier élément soit le plus grand. Continuez ensuite à ajuster le tas et
échangez l' élément supérieur avec le dernier élément pour obtenir le deuxième élément le plus grand. L'échange, la reconstruction et l'échange sont répétés de cette manière.

Insérez la description de l'image ici

9 n'est plus utilisé pour le tri, nous le traiterons comme un déplacement hors du tableau

Ensuite, réajustez la structure pour continuer à répondre à la définition du tas

Insérez la description de l'image ici

Ensuite, échangez l'élément supérieur 8 avec le dernier élément 5 pour obtenir le deuxième élément le plus grand 8.

Insérez la description de l'image ici

Les opérations suivantes répètent ce qui précède et obtiennent finalement une séquence ordonnée

Insérez la description de l'image ici

Résumé de l'enseignant

1. Construisez la séquence désordonnée en une pile et sélectionnez la grande pile supérieure ou la petite pile supérieure selon les exigences de l'ordre croissant et décroissant;

2. Échangez l’élément supérieur par l’élément final [déposez le plus grand élément à la fin du tableau

3. Réajustez la structure pour répondre à la définition du tas, puis continuez à échanger l'élément supérieur et l'élément final actuel, et répétez les étapes d'ajustement + d'échange jusqu'à ce que toute la séquence soit en ordre.

Code

package;

import java.util.Arrays;

//堆排序
//2021年1月31日21:26:04
//作者 @王
public class HeapSort {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		int arr[] ={
    
    4,6,8,5,9};
		heapSort(arr);
	}
	
	//编写堆排序的方法
	public static void heapSort(int[] arr){
    
    
		int temp = 0;
		System.out.println("堆排序");
		
//		//分步完成
//		adjustHeap(arr, 1, arr.length);
//		System.out.println("第一次调整"+Arrays.toString(arr));
//		adjustHeap(arr, 0, arr.length);
//		System.out.println("第二次调整"+Arrays.toString(arr));
		//将我们的数组变成一个大顶堆
		for (int i = arr.length/2 -1; i >=0; i--) {
    
    
			adjustHeap(arr, i, arr.length);
		}

		//将堆顶元素与末尾元素交换,将最大元素沉到数组末端
		//重新调整结构,使其满足堆定义,然后继续减缓堆顶元素与当前末尾元素,反复
		//执行调整+交换步骤直到整个序列有序
		for(int j = arr.length-1;j>0;j--){
    
    
			//交换
			temp = arr[j];
			arr[j] = arr[0];
			arr[0] = temp;
			adjustHeap(arr, 0, j);
		}
	}
	//将一个数组(二叉树),调整成一个大顶堆或者小顶堆
	/**
	 * 功能:完成将以i对应的非叶子结点的树调整成大顶堆
	 * 举例  4,6,8,5,9  => i=1   => 得到 4,9,8,5,6
	 * @param arr
	 * @param i		表示非叶子节点在数组中的索引 
	 * @param length	表示对多少个元素继续调整,length是在逐渐的减少
	 */
	public static void adjustHeap(int arr[],int i,int length){
    
    
		int temp = arr[i];//取出当前元素的值,保存在临时变量
		//开始调整
		//1. k = i*2+1   k 是i节点的左子节点
		for (int k = i * 2 +1; k < length; k = k * 2 +1) {
    
    
			if(k + 1 < length && arr[k] < arr[k+1]){
    
    
				//说明左子节点的值小于右子节点的值
				k++;//k指向右子节点
			}
			if(arr[k] > temp){
    
    
				//如果子节点大于父节点
				arr[i] = arr[k];
				i = k;//i指向K  继续循环比较 
			}else{
    
    
				break;
			}
		}
		//当for循环结束后,我们已经将以i为父节点的树的最大值,放在了最顶上(局部)
		arr[i] = temp;
	}

}

Je suppose que tu aimes

Origine blog.csdn.net/qq_22155255/article/details/113823058
conseillé
Classement