c++堆排序實現(heapsort) (演算法導論)
阿新 • • 發佈:2019-01-07
利用最大堆實現。
最大堆:最大堆性質是除了根結點意外的所有結點 i 都要滿足A[parent[i]] >= A[i]
需要利用到的一個性質:當用陣列表示儲存n個元素的堆時,葉結點的下標分別是n/2, n/2+1, n/2 + 2, ......,n - 1. (下標從0開始)
需要用到的函式有:
void max_heapify(int *a, int i) //通過讓a[i]的值在最大堆中“逐級下降”,從而使得以下標i為根結點的字數重新遵循最大堆的性質。O(lgn)
void build_max_heap(int *a) //對樹中非葉結點都呼叫一次max_heapify(a, i)。 O(n)
void heapsort(int *a, int n) //對長度為n的陣列a呼叫堆排序。 O(nlgn)
//heapsort.cpp inline void swap(int &a, int &b) { int t = a; a = b; b = t; } inline int parent(int i) { return (i-1) >> 1; } //下標都是從0開始,與算導上不一樣 inline int left(int i) { return (i << 1) + 1; } inline int right(int i) { return (i << 1) + 2; } int heap_size, heap_length; //heap_length是陣列元素個數,heap_size是有多少個元素儲存在陣列中。0<=heap_size<=heap_length void max_heapify(int *a, int i) { //O(lgn), 維護heap的性質,使得以下標i為根結點的子樹重新遵循最大堆的性質 int l = left(i), r = right(i); int largest = 0; if (l < heap_size && a[l] > a[i]) largest = l; else largest = i; if (r < heap_size && a[r] > a[largest]) largest = r; if (largest != i) { swap(a[i], a[largest]); max_heapify(a, largest); } } void build_max_heap(int *a) { //O(n), 對樹中非葉結點都呼叫一次 max_heapify heap_size = heap_length; for (int i = heap_length/2 - 1; i >= 0; --i) //可以證明下標為n/2-1到0的結點為非葉結點 max_heapify(a, i); //i逆序遞減的原因:任何時候對結點i呼叫max_heapify,該i的兩個子樹都是最大堆 } void heapsort(int *a, int n) { //O(nlgn),呼叫heapsort(a, n)對陣列a排序 heap_length = n; build_max_heap(a); for (int i = heap_length - 1; i >= 1; --i) { swap(a[0], a[i]); --heap_size; max_heapify(a, 0); } }