Algoritmo de clasificación ---------- clasificación de montón

Tipo de pila

Introducción

La ordenación de pila también es una especie de selección , la peor y mejor complejidad de tiempo promedio es O (nlogn), que es una ordenación inestable

Es un árbol binario completo, el valor de cada nodo es mayor o igual que el valor de sus nodos secundarios izquierdo y derecho ===> empuje grande, tenga en cuenta que no requiere la relación de tamaño entre los nodos secundarios izquierdo y derecho , de lo contrario es un pequeño montón superior

Idea básica

1. Construya la secuencia para clasificarla en un montón superior grande

En este momento, el valor máximo de toda la secuencia es el nodo raíz del elemento del montón.

Cámbielo con el último elemento, y el final es el valor máximo en este momento.

Luego reconstruya los n-1 elementos restantes en una pila, de modo que se obtenga el siguiente valor más pequeño de n elementos. Tal ejecución repetida resultará en una secuencia ordenada.

Diagrama

img

El ejemplo en el video instructivo tiene una matriz {4,6,8,5,9} usando el algoritmo de clasificación de pila

Inserte la descripción de la imagen aquí

Luego comenzamos desde el último nodo no hoja (el nodo hoja naturalmente no necesita ser ajustado, el primer nodo no hoja arr.length / 2-1 = 5 / 2-1 = 1, que son los 6 nodos debajo ), Ajuste de izquierda a derecha y de abajo hacia arriba .

Inserte la descripción de la imagen aquí

Luego encuentre el segundo nodo no hoja 4, encuentre que 9 elementos de 4, 9, 8 son los más grandes y que 4 y 9 se intercambian

Inserte la descripción de la imagen aquí

En este momento, el intercambio provocó que la estructura de la subraíz [4, 5, 6] fuera caótica y continuara ajustándose. En [4, 5, 6], 6 es el más grande y 4 y 6 se intercambian .

Inserte la descripción de la imagen aquí

Hasta ahora, nuestro gran impulso se ha completado

Segundo paso

Cambie el elemento superior con el último elemento para hacer que el último elemento sea el más grande. Luego, continúe ajustando el montón e
intercambie el elemento superior con el último elemento para obtener el segundo elemento más grande. El intercambio, la reconstrucción y el intercambio se repiten de esta manera.

Inserte la descripción de la imagen aquí

9 ya no se usa para ordenar, lo trataremos como si se estuviera moviendo fuera de la matriz

Luego, reajuste la estructura para continuar cumpliendo con la definición del montón

Inserte la descripción de la imagen aquí

Luego intercambie el elemento superior 8 con el último elemento 5 para obtener el segundo elemento más grande 8.

Inserte la descripción de la imagen aquí

Las operaciones posteriores repiten lo anterior y finalmente obtienen una secuencia ordenada

Inserte la descripción de la imagen aquí

Resumen del profesor

1. Construya la secuencia desordenada en una pila y seleccione la pila superior grande o la pila superior pequeña de acuerdo con los requisitos de orden ascendente y descendente;

2. Cambie el elemento superior con el elemento final [hundir el elemento más grande hasta el final de la matriz

3. Vuelva a ajustar la estructura para cumplir con la definición del montón, y luego continúe intercambiando el elemento superior y el elemento final actual, y repita los pasos de ajuste + intercambio hasta que toda la secuencia esté en orden.

Código

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;
	}

}

Supongo que te gusta

Origin blog.csdn.net/qq_22155255/article/details/113823058
Recomendado
Clasificación