java最大最小堆

堆是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于(或不小于)其左孩子和右孩子节点的值。
最大堆和最小堆是二叉堆的两种形式。
最大堆:根结点的键值是所有堆结点键值中最大者。
最小堆:根结点的键值是所有堆结点键值中最小者。
 1 public class HeapSort {
 2 
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8 
 9         int a[] = new int[6];
10         a[0] = 7;
11         a[1] = 5;
12         a[2] = 3;
13         a[3] = 8;
14         a[4] = 9;
15         a[5] = 2;
16         
17         // 这是通过每次向上调整得到最大堆,整体自上而下
18         for (int i = a.length / 2 - 1; i < a.length; i++) {
19             shiftUp(a, i, a.length);
20         }
21         for (int i = 0; i < a.length; i++) {
22             System.out.println(a[i]);
23         }
24         for (int i = a.length - 1; i > 0; i--) {
25             int temp = a[i];
26             a[i] = a[0];
27             a[0] = temp;
28             shiftUp(a, i - 1, i);
29         }
30 
31         //这是通过每次向下调整得到最大堆,整体自底向上(推荐)
32         for (int i = (a.length) / 2 - 1; i >= 0; i--) {
33             shiftDown(a, i, a.length);
34         }
35         for (int i = 0; i < a.length; i++) {
36             System.out.println(a[i]);
37         }
38         for (int i = a.length - 1; i > 0; i--) {
39             int temp = a[i];
40             a[i] = a[0];
41             a[0] = temp;
42             shiftDown(a, 0, i);
43         }
44 
45         //输出排序结果
46         for (int i = 0; i < a.length; i++) {
47             System.out.println(a[i]);
48         }
49     }
50 
51     //最大最小堆是相对的,只要稍微修改就可以
52     public static void shiftDown(int a[], int i, int length) {
53         while (2 * i + 1 < length) {
54             int j = (i << 1) + 1;
55             if (j + 1 < length && a[j] < a[j + 1])
56                 j = j + 1;
57             if (a[i] < a[j]) {
58                 int temp = a[i];
59                 a[i] = a[j];
60                 a[j] = temp;
61             } else {
62                 break;
63             }
64             i = j;
65         }
66     }
67 
68     public static void shiftUp(int a[], int i, int length) {
69         while (i > 0) {
70             int j = (i & 1) == 1 ? i + 1 : i - 1;
71             int parent = (i - 1) >> 1;
72             if (j < length && a[j] > a[i]) {
73                 i = j;
74             }
75             if (a[parent] < a[i]) {
76                 int temp = a[i];
77                 a[i] = a[parent];
78                 a[parent] = temp;
79             }
80             i = parent;
81         }
82     }
83 }

以上代码实现两种方式建立大顶堆并且实现排序。

堆很常用,用于排序效率很高。

并且在top k问题中很常见:

求top max k问题,可以用小顶堆实现,首先建立一个k大小的小顶堆,后面的数据依次与堆顶的最小值比较,如果比最小值大,则交换两个之后重新调整堆,最后就是top max k。

同理,top min k,用大顶堆实现。

原文地址:https://www.cnblogs.com/nannanITeye/p/3356735.html