基於陣列的堆排序演算法的C語言實現
阿新 • • 發佈:2019-01-28
實現如下:
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操作執行時間的漸近上界為
build_max_heap將一個數組建立為最大堆,從最後一個非葉子節點到根節點依次分別呼叫max_heapify函式即可。其操作時間的漸近確界為
heap_sort函式對n個數進行堆排序,每次將最大堆的第一個元素和最後一個元素交換,得到最大的元素,將堆的元素個數減一後再對堆的根節點進行max_heapify操作,得到當前堆中最大元素,迴圈n-1次即可排序陣列。其操作時間的漸近確界為
其上所有演算法複雜度計算方法見演算法導論第六章,涉及主定理不再贅述。