堆排序核心是引用了堆这种数据结构的特点,底层是由二叉树实现;
主要涉及的操作是堆中替换最大节点后所用到的下沉操作:
具体操作核心是:
首先在一个while循环中,先比较该节点左右子节点的大小,在用该节点去比较两个节点中较大的一个节点,如果父亲节点比该节点小则交换位置,否则跳出循环,直到比到根节点while循环结束。
而堆排序一方面是对从第一个非叶子节点的父节点开始进行下沉,另一方面是对让每一个节点与堆顶元素进行交换并执行下沉操作;
经过这样两方面的排序,最终得到正确排序顺序。
import java.util.Arrays;
public class HeapSort{
public static void main(String[] args) {
int[] arr = {16, 7, 3, 20, 17, 8};
heapSort(arr);
for (int i : arr){
System.out.print(i+ " ");
}
}
public static void heapSort(int[] arr){
//对从第一个非叶子节点的父节点开始进行下沉操作
for (int i = (arr.length - 1) / 2; i >= 0; i --){
adjustHeap(arr,i,arr.length);
}
//与堆顶交换元素进行下沉操作
for (int i = arr.length-1; i > 0; i --){
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
adjustHeap(arr,0,i);
}
}
private static void adjustHeap(int[] arr,int parent,int length){
int temp = arr[parent];
int leftChild = parent * 2 + 1;
while(leftChild < length){
int rightChild = leftChild + 1;
if (rightChild < length && arr[rightChild] > arr[leftChild])
leftChild ++;
if (temp >= arr[leftChild])
break;
//把孩子节点的值赋给父亲
arr[parent] = arr[leftChild];
parent = leftChild;
leftChild = 2 * parent + 1;
}
arr[parent] = temp;
}
}