Implementación de Java: árbol binario de estructura de datos (cuatro): clasificación de montón

Estructura de datos del árbol binario (cuatro): clasificación de montón

Introducción básica :

El tipo de pila es un tipo de selección , su peor, mejor, promedio de complejidad práctica es O (nlogn), también es un tipo inestable .

Introducción al montón:
Heap es un árbol binario completo con propiedades especiales :
gran montón :
el valor de cada nodo es mayor o igual que el valor de sus nodos secundarios izquierdo y derecho.
Montón superior pequeño :
el valor de cada nodo es menor o igual que el valor de sus nodos secundarios izquierdo y derecho.

Diagrama esquemático del montón grande :
Inserte la descripción de la imagen aquí
numeramos los nodos del montón por capa, y el mapa de la matriz es arr [50,45,40,20,25,35,30,10,15];
es decir, arr [i]> = arr [2 i + 1] && arr [i]> = arr [2 i + 2]; (i es el número de nodo correspondiente)
(Nota: el tamaño del montón superior no requiere la relación de tamaño entre los nodos secundarios izquierdo y derecho).

Diagrama esquemático de la pila superior pequeña :
Inserte la descripción de la imagen aquí
arr [i] <= arr [2 i + 1] && arr [i] <= arr [2 i + 2].

Clasificación de montón:
generalmente, el orden ascendente adopta un montón superior grande y el orden descendente adopta un montón superior pequeño.

La idea básica de la clasificación de montones:
1. Primero construya la secuencia para clasificar en un montón superior grande.
2. En este momento, el valor máximo de toda la secuencia es el nodo raíz del gran pilote superior.
3. Intercambie el valor de este nodo raíz con el valor final de la secuencia a ordenar, esta vez el final es el valor máximo.
4. Luego reconstruya los n-1 árboles restantes en un montón, de manera que se obtenga el valor máximo de n-1 elementos, que se intercambia con el último elemento de n-1 elementos.
5. Ejecute repetidamente de esta manera para obtener una secuencia ordenada ascendente.

Ejemplo gráfico:
Primero, definimos un arreglo:
arr [4,5,8,5,9] Constrúyelo
en un árbol como se muestra en la figura:
Inserte la descripción de la imagen aquí
De acuerdo con la idea, lo siguiente que debes hacer es construirlo en una gran pila superior.
La idea de construirlo en una gran pila superior es la siguiente:
1. Primero, primero buscamos el último nodo sin hoja (disponible en arr.length / 2-1) del árbol (es decir, el nodo 6), y dejemos que 6 nodos y sus hijos izquierdo y derecho Se comparan los nodos y el máximo de los tres se intercambia con el nodo 6.
El resultado del intercambio es el siguiente:
Inserte la descripción de la imagen aquí
Entonces, la matriz correspondiente al árbol se convierte en
arr [4,9,8,5,6]

2. Luego, ajuste de izquierda a derecha, de abajo hacia arriba,
y luego busque el segundo nodo no hoja (es decir, 4 nodos) y realice la misma comparación e intercambio, y obtenga lo siguiente:
Inserte la descripción de la imagen aquí
3. En este punto, se encuentra que el nodo 4 reemplazado todavía es más que su izquierda El nodo hijo es pequeño, intercambie de nuevo y finalmente obtenga lo siguiente:
Inserte la descripción de la imagen aquí
En este momento, obtenga la matriz
arr [9,6,8,5,4] y
luego intercambie el nodo raíz (9 nodos) con el final, y obtenga lo siguiente:
Inserte la descripción de la imagen aquí
finalmente y así sucesivamente, continúe comparando , el intercambio , la creación , y, finalmente, conseguir una serie ascendente.

El código de referencia de Java es el siguiente:

import java.util.Arrays;

public class HeapSort {
    
    
	public static void main(String[] args) {
    
    
		//升序排列
		int arr[]= {
    
    4,6,8,5,9};
		heapSort(arr);
		System.out.println(Arrays.toString(arr));
	}
	//堆排序方法
	public static void heapSort(int[] arr) {
    
    
		int temp=0;
		for(int i=arr.length/2-1;i>=0;i--) {
    
    
			makeBigHeap(arr,i,arr.length);
		}
		for(int j=arr.length-1;j>0;j--) {
    
    
			temp=arr[j];
			arr[j]=arr[0];
			arr[0]=temp;
			makeBigHeap(arr,0,j);
		}
		
	}
	
	/*
	 * 将数组调整成大顶堆的方法:将以i对应的非叶子节点树调整成大顶堆
	 * arr:待调整数组
	 * i:非叶子节点在数组中索引
	 * length:调整数组的长度
	 */
	public static void makeBigHeap(int arr[],int i,int length) {
    
    
		int temp=arr[i];//取出当前元素,保存在临时变量
		//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;//继续循环比较
			}else {
    
    
				break;
			}
		}
		arr[i]=temp;//将temp赋值放到调整后的位置

	}
}

Supongo que te gusta

Origin blog.csdn.net/qq_45273552/article/details/109101049
Recomendado
Clasificación