堆
堆的定义如下:
- 堆是一颗完全二叉树;
- 堆中的某个节点的值总是不大于或不小于其孩子节点的值;
- 堆中每个节点的子堆都是堆;
当父节点的键值总是大于或者等于任何一个子节点的键值时为最大堆。当父节点的键值总是小于或者等于任何一个子节点的键值时未最小堆。如下图所示,左边为最大堆,右边为最小堆。
算法思想
首先把有n个元素的数组a初始化创建为最大堆,然后循环执行如下过程直到数组为空为止:
- 把堆顶a[0]元素(为最大元素)和当前最大堆的最后一个元素交换;
- 最大堆元素个数减一;
- 由于第一步后根结点不再满足最大堆的定义,因此调整根结点使之满足最大堆的定义;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| void CreateHeap(int a[], int n, int h) { int i, j, flag; int temp; i = h; j = 2 * i + 1; temp = a[i]; flag = 0; while (j < n && flag != 1) { if (j < n - 1 && a[j] < a[j + 1]) j++; if (temp > a[i]) { flag = 1; } else { a[i] = a[j]; i = j; j = 2 * i + 1; } } a[i] = temp; }
|
1 2 3 4 5 6
| void InitCreateHeap(int a[], int n) { int i; for (i = (n - 2)/2; i >= 0; i--) CreateHeap(a, n, i); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void HeapSort(int a[], int n) { int i; int temp; InitCreateHeap(a, n); for (i = n - 1; i > 0; i--) { temp = a[0]; a[0] = a[i]; a[i] = temp; CreateHeap(a, i, 0); } }
|