最大堆构建和堆排序

1 输入一个任意长度的无规律数组,把该数组构建为最大堆

2 用构建好的最大堆,进行堆排序

 1 public class Solution {
 2     
 3     /**
 4      * 构建堆
 5      * @param array
 6      */
 7     public static void buildMaxHeap(int[] array) {
 8         
 9     /*    for (int i = array.length / 2; i >= 0; i--) {
10             adjust(array, i, array.length);    
11         }*/
12         /** 以树的最后一个节点的父节点为根开始调整  */
13         int last = array.length - 1;
14         int pos = (last - 1) / 2;
15         while (pos >= 0) {
16             adjust(array, pos--, array.length);
17         }
18     }
19     
20     
21     /**
22      * 把以root为根的那棵子树调整为最大堆, 此时以root为根的左右子树都以调整为最大堆
23      * @param array
24      * @param root
25      * @param len
26      */
27     public static void adjust(int[] array, int root, int len) {
28         int l = root * 2 + 1;
29         int r = root * 2 + 2;
30         int largest = root;
31         
32         /** 特别要考虑满二叉树的情况 */
33         //parent节点有左孩子
34         if (l < len && array[l] > array[largest]) {
35                 largest = l;
36         }
37         //parent节点有右孩子
38         if (r < len && array[r] > array[largest]) {
39                 largest = r;
40         }
41         
42         //如果以root为根的堆
43         if (largest != root) {
44             swap(array, root, largest);
45             adjust(array, largest, len);
46         }
47     }
48     
49     
50     /**
51      *  堆排序函数
52      * @param array
53      * @param len
54      */
55     public static void heapSort(int[] array) {
56         
57         int len = array.length;
58         
59         while (len > 1) {
60             /** 堆顶的元素为数组中所有元素的最大值
61                                 出堆顶,把堆对应树的最后那个节点放到堆顶(从堆顶向下调整)
62                                 此时,堆对应树的最后那个节点位置为空,把刚出的堆顶最大值放入该空位 */
63             swap(array, 0, len - 1); //拿堆对应的树的最后一个节点与根节点交换
64             len--;
65             adjust(array, 0, len);
66         }
67     }
68     
69     public static void print(int[] array) {
70         for (int i = 0; i < array.length;  i++) {
71             System.out.println(i + ", " + array[i]);
72         }
73     }
74     
75     public static void swap(int[] array, int t1, int t2) {
76         int temp = array[t1];
77         array[t1] = array[t2];
78         array[t2] = temp;
79     }
80     
81     
82     
83     public static void main(String[] args) {
84         
85         //生成随机数数组
86         int[] array = { 53, 17, 78, 9, 45, 65, 87};
87         
88         buildMaxHeap(array);
89         System.out.println("建堆完成:");
90         print(array);
91         System.out.println("------------------");
92         
93         heapSort(array);
94         print(array);
95     }
96 }

 上述方案调整堆的原理为:

    1)叶子节点,无子树,可以把叶结点看作为一棵树,为最大堆

    2)从最后一个叶节点开始

    3)让pos指向该叶结点的父节点,pos指向一个子树,其孩子(为叶结点)已是最大堆,然后我们只要把这棵树调整为最大堆

    4)pos减1,走3),直到pos指向数组索引0处,把堆顶调整完成

原文地址:https://www.cnblogs.com/asnjudy/p/5701668.html