本文代码均转自:
1 public class HeapSort {
2 public static int[] maxHeap(int[] array) {
3 // 1.构建大顶堆
4 for (int i = array.length / 2 - 1; i >= 0; i--) {
5 // 从第一个非叶子结点从下至上,对于数组从右至左调整结构
6 adjustHeap(array, i, array.length);
7 }
8 return array;
9 }
10
11 private static void adjustHeap(int[] array, int i, int length) {
12 int parent = array[i];
13 for (int k = 2 * i + 1; k < length; k = k * 2 + 1) {
14 // 2*i+1表示左节点,k = k * 2 + 1表示继续调整子节点
15 if (k + 1 < length && array[k] < array[k + 1])
16 k = k + 1;// 找到子节点中更大的节点
17 if (array[k] > parent) {
18 array[i] = array[k];// 父节点变为更大的值
19 i = k;// 修改i的值,使之成爲新的要調整的父節點
20 } else {
21 break;// 表示无需调整,因为是自底向上的
22 }
23 }
24 array[i] = parent;// 将temp值放到最终的位置
25 }
26
27 public static void main(String[] args) {
28 int[] array = { 4, 6, 8, 5, 9 };
29 int[] maxHeap = maxHeap(array);
30 for (int i : maxHeap) {
31 System.out.print(i + " ");
32 }
33 }
34 }
建大根堆堆思路整理:
1.找到堆中第一个非叶子结点(N0),从它开始调整左右子树。
*第一个非叶子结点的下标为:length/2 -1
*左右子树调整过程:找到其中的较大值结点Ngreater,然后与N0值作比较,如果N0<Ngreater则将两者交换,并继续调整Ngreater的叶子结点(虽然是自底向上调整的,
但是可能在某些parent下降的过程中破坏了底下子树的大小排列规则。)如果N0>=Ngreater直接开始(退出了adjustHeap函数)调整下一个非叶子结点。
2.通过循环调用adjustHeap将所有的非叶子几点调整完成。
堆排序思路:
1.建立初始堆后,将堆顶元素(最大值)与堆中最后一个元素交换,然后调整数组(堆)中的前n-1个元素。(即把数组末尾作为有序区)
2.调整到堆中只剩一个元素时,排序完成。
堆排序代码:
1 public static void sort(int []arr){
2 //1.构建大顶堆
3 for(int i=arr.length/2-1;i>=0;i--){
4 adjustHeap(arr,i,arr.length);
5 }
6 //2.调整堆结构+交换堆顶元素与末尾元素
7 for(int j=arr.length-1;j>0;j--){
8 swap(arr,0,j);//将堆顶元素与末尾元素进行交换
9 adjustHeap(arr,0,j);//重新对堆进行调整
10 }
11 }
来源:https://www.cnblogs.com/singular/p/10488604.html