實現如下:
int getParent(int c);int getLeft(int p);int getRight(int p);void swap(int *p1, int *p2);void heap_sort(int *source, int length);void max_heapify(int *source, int length, int loc);void build_max_heap(int *source, int length);void heap_sort_iteration(int *source, int length);void max_heapify_iteration(int *source, int length, int loc);void build_max_heap_iteration(int *source, int length);int getParent(int c) { return (c - 1) / 2;}int getLeft(int p) { return p * 2 + 1;}int getRight(int p) { return p * 2 + 2;}void swap(int *p1, int *p2) { int temp = *p1; *p1 = *p2; *p2 = temp;}void max_heapify(int *source, int length, int loc) { int l = getLeft(loc); int r = getRight(loc); int max = loc; if (l < length && source[l] > source[max]) max = l; if (r < length && source[r] > source[max]) max = r; if (max == loc) return; swap(source + max, source + loc); max_heapify(source, length, max);}void build_max_heap(int *source, int length) { for (int i = getParent(length - 1); i >= 0; --i) { max_heapify(source, length, i); }}void heap_sort(int *source, int length) { build_max_heap(source, length); for (int i = length - 1; i > 0; --i) { swap(source, source + i); max_heapify(source, i, 0); }}void max_heapify_iteration(int *source, int length, int loc) { int l, r; int max = loc; while (loc < length) { l = getLeft(loc); r = getRight(loc); if (l < length && source[l] > source[max]) max = l; if (r < length && source[r] > source[max]) max = r; if (max == loc) return; swap(source + max, source + loc); loc = max; }}void build_max_heap_iteration(int *source, int length) { for (int i = getParent(length - 1); i >= 0; --i) { max_heapify_iteration(source, length, i); }}void heap_sort_iteration(int *source, int length) { build_max_heap(source, length); for (int i = length - 1; i > 0; --i) { swap(source, source + i); max_heapify_iteration(source, i, 0); }}
堆排序是不穩定原地的排序。
該程式中使用的數組作為表示堆的資料結構,其計算左子女,右子女以及父節點的座標的方式如parent,left_child,right_child所示。
max_heapify使其保持最大堆的性質,假設p節點左右兩顆子樹都是最大堆,max_heapify使p節點保持最大堆的性質,選取p節點的左右子女中最大的與p節點交換,然後遞迴的對交換後的節點繼續進行max_heapify操作,直到到達葉子結點。max_heapify操作已耗用時間的漸近上界為 Ο(h) Ο(h)h為待動作節點的高度。
build_max_heap將一個數組建立為最大堆,從最後一個非葉子節點到根節點依次分別調用max_heapify函數即可。其操作時間的漸近確界為 Ο(n) Ο(n)。
heap_sort函數對n個數進行堆排序,每次將最大堆的第一個元素和最後一個元素交換,得到最大的元素,將堆的元素個數減一後再對堆的根節點進行max_heapify操作,得到當前堆中最大元素,迴圈n-1次即可排序數組。其操作時間的漸近確界為 Ο(nlogn) Ο(nlogn)。
其上所有演算法複雜度計算方法見演算法導論第六章,涉及主定理不再贅述。