堆一个常见的应用:作为高效的优先队列.
我们可以在一个线性时间内将一个无序数组构造成一个最大堆,并且在O(lgn)的时间内调整堆.堆排序的时间复杂度为:O(nlgn).
1 1 #include <stdio.h>
2 2 #include <stdlib.h>
3 3
4 4 void build_heap(int data[], int);
5 5 void adjust_heap(int data[], int);
6 6 void heap_sort(int data[], int);
7 7 int sub_max_heap(int data[], int, int);
8 8
9 9 int main(int argc, char *argv[])
10 10 {
11 11 int i;
12 12 int data[12] = {6, 10, 3, 5, 12, 8, 4, 23, 1, 2, 9, 7 };
13 13
14 14 heap_sort(data, 12);
15 15
16 16 for (i = 0; i < 12; ++i)
17 17 {
18 18 printf("%d ", data[i]);
19 19 }
20 20
21 21 printf("
");
22 22 return 0;
23 23 }
24 24
25 25 void heap_sort(int data[], int num)
26 26 {
27 27 int i = 1;
28 28 build_heap(data, num);
29 29
30 30 for (i = 1; i < num; ++i)
31 31 {
32 32 int temp;
33 33 temp = data[0];
34 34 data[0] = data[num - i];
35 35 data[num - i] = temp;
36 36
37 37 adjust_heap(data, num - i);
38 38 }
39 39
40 40 }
41 41
42 42
43 43 void build_heap(int data[], int num)
44 44 {
45 45 int 46
46 47 for (i = num / 2 - 1; i >= 0; --i)
47 48 {
48 49 k = sub_max_heap(data, num, i);
49 50 if (k == i)
50 51 continue;
51 52
52 53 while (2 * k + 1 < num)
53 54 {
54 55 p = k;
55 56 k = sub_max_heap(data, num, p);
56 57 if (k == p)
57 58 break;
58 59 }
59 60 }
60 61
61 62 }
62 63
63 64
64 65 void adjust_heap(int data[], int num)
65 66 {
66 67 int temp;
67 68 int k, p;
68 69
69 70 k = 0;
70 71 while(2 * k + 1 < num)
71 72 {
72 73 p = k;
73 74 k = sub_max_heap(data, num, p);
74 75 if (k == p)
75 76 break;
76 77 }
77 78
78 79
79 80 }
80 81 /*
81 82 int sub_max_heap(int data[], int num, int i)
82 83 {
83 84 int k;
84 85
85 86 if (2 * i + 2 <= num - 1 && data[2 * i + 1] > data[2 * i + 2])
86 87 k = 2 * i + 1;
87 88 else if (2 * i + 2 <= num - 1)
88 89 k = 2 * i + 2;
89 90 else
90 91 k = 2 * i + 1;
91 92
92 93 if (data[k] > data[i])
93 94 {
94 95 int temp;
95 96 temp = data[k];
96 97 data[k] = data[i];
97 98 data[i] = temp;
98 99 }
99 100
100 101 return k;
101 102
102 103 }
103 104 */
104 105 /*返回一个最大值的标记.即结点i的值,结点i的左孩子值和结点i的右孩子值中的最大值的标记*/
105 106 int sub_max_heap(int data[], int num, int i)
106 107 {
107 108 int largest;
108 109 int l, r;
109 110
110 111 l = 2 * i + 1;
111 112 r = 2 * i + 2;
112 113
113 114 if (l <= num - 1 && data[l] > data[i])
114 115 largest = l;
115 116 else
116 117 largest = i;
117 118
118 119 if (r <= num - 1 && data[r] > data[largest])
119 120 largest = r;
120 121 if (largest != i)
121 122 {
122 123 int temp;
123 124 temp = data[i];
124 125 data[i] = data[largest];
125 126 data[largest] = temp;
126 127 }
127 128
128 129 return largest;
129 130 }