堆排序
通常所说的堆是指二叉堆,其定义为:
n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系时,被称为堆:ki <= k2i 并且 ki <= k2i+1 , 或者 ki >= k2i 并且 ki >= k2i+1。 若将此序列看成是一个完全二叉树,则二叉树中所有非叶子结点的值都不大于(或者不小于)其左、右孩子结点的值,父结点的值比较大的叫做最大堆(或者大根堆),父结点比较小的叫做最小堆(或者小根堆)。显而易见,在最大堆中,堆顶的元素最大,在最小堆中,堆顶的元素最小。堆排序就是利用大根堆的性质进行排序的一种算法,将数组建堆后,每次将堆顶元素(为最大元素)取出放置与数组的最后,再将除最大元素外的其余元素建堆,取出第二大元素...依此递归进行即可。
时间复杂度:O(n * logn)
稳定性:不稳定
实现:
1: /*
2: * 假设k的左右子树满足大根堆性质, 使以k为根的子树成为大根堆
3: */
4: void
5: max_heapify(int a[], int n, int k)
6: {
7: int i;
8: int key = a[k];
9:
10: for (i = 2*k+1; i < n; i = i*2+1) {
11: if (i < n - 1 && a[i] < a[i+1])
12: ++i;
13: if (a[i] <= key)
14: break;
15: a[k] = a[i];
16: k = i;
17: }
18: a[k] = key;
19: }
20:
21: void
22: build_max_heap(int a[], int n)
23: {
24: int i;
25:
26: for (i = n/2; i >= 0; --i) {
27: max_heapify(a, n, i);
28: }
29: }
30:
31: void
32: heap_sort(int a[], int n)
33: {
34: int i;
35:
36: build_max_heap(a, n);
37: for (i = n - 1; i > 0; --i) {
38: swap(a[0], a[i]);
39: max_heapify(a, i, 0);
40: }
41: }
42: