首先,推薦你們去看下《算法導論》,那是算法聖經,講得很是詳細,本文中的代碼大部分是將其中的僞代碼用C/C++實現出來ios
雖然書上有堆排序(heapsort)的概念的詳細解釋,網絡上介紹堆排序的講解也基本都有描述,我這仍是將一些基本概念寫出來:算法
堆:(二叉)堆數據結構是一種數組對象,能夠被視爲一棵徹底二叉樹,樹中的每一個結點與數組中存放該結點值的那個元素對應。以下圖所示:api
假設存儲數組下標從1開始,則給定某個結點的標 i, 易得其父結點下標爲 ⌊i / 2⌋, 左兒子結點下標爲 2 * i,右結點下標爲2 * i + 1數組
二叉堆有兩種:最大堆和最小堆(小根堆),上圖即爲最大堆及其數組表示網絡
最大堆:在最大堆中,最大堆特性是指除了根之外的每一個結點 i ,有 A[PARENT( i )] ≥ A[ i ](PARENT(i)是指 i 結點的父結點), 即某個結點的值至可能是和其父結點的值同樣大,這樣,堆中的最大元素就存放在根結點中;而且,在以某一個結點爲根的子樹中,各結點的值都不大於該子樹結點的值數據結構
最小堆:組織方式與最大堆正好相反;最小堆特性就是除了根之外的每一個結點i,有A[PARENT( i )] ≤ A[ i ],最小元素在根部ui
堆排序:堆排序的實現利用了最大堆(最小堆)的「堆的最大(小)元素就存放在根結點中」這一特性,能夠在每次堆化後儘快地找到當前堆的最大(小)元素spa
在堆排序中,一般使用的是最大堆,而最小堆一般在構造優先隊列時使用,關於優先隊列的實現後面的總結中會出現.net
堆排序的運行時間爲O(n lgn),是一種原地排序算法:在任什麼時候候,數組中只有常數個元素存儲在輸入數組之外code
具體實現看如下代碼:
/* ***Author: asd ***Data: 2012/7/13 ***blog:http://blog.csdn.net/zhengjj_asd ***HeapSort */ #include <iostream> using namespace std; //利用異或交換 a, b 的值 #define swap(a, b) { a^= b^= a^= b;} //輸出 a[1..size] 的值 void arr_display(int *a, int size) { for(int i = 1; i < size; ++ i) cout << a[i] << " "; cout << a[size] << endl; } //調用是假定 a[left], a[right] 爲根的兩棵二叉樹都是已成最大堆 //可是a[i]可能小於它的子節點,違反了最大堆的性質 //Max_Heapify使a[i]在最大堆中「降低」,使以i爲根的子樹成爲最大堆 void Max_Heapify(int *a, int size, int i) { int left = 2 * i; int right = 2 * i + 1; int largest; if(left <= size && a[left] > a[i]) largest = left; else largest = i; if(right <= size && a[right] > a[largest]) largest = right; if(largest != i) { swap(a[largest], a[i]); Max_Heapify(a, size, largest); } } //自底向上地將一個數組a[1..n]變成一個最大堆 //在數組a[1..n]中,a[(n / 2) + 1..n]是樹中的葉子 //每一個都是隻含一個元素的堆,對其餘結點(也就是非葉子結點)都調用一次Max_Heapify void Build_Max_Heap(int *a, int size) { for(int i = size / 2; i >= 1; -- i) Max_Heapify(a, size, i); } //先將數組a[1..n]用Build_Max_Heap構形成一個最大堆 //由於a[1]爲堆中最大的元素,因此能夠經過其與a[n]交換,使其到達最終正確的位置 //而後在堆中去掉交換後的結點n,由於結點1爲根的子女仍然仍是最大堆 //而交換後的結點1可能就違背了最大堆的性質,只要用Max_Heapify進行維護 //使a[1..n-1]仍然爲最大堆,而後又交換a[1]與a[n-1],再調用Max_Heapify //重複這個過程可以使堆的大小從n-1一直降到2,這時a[1..n]即爲原數組按非降序排序結果 void HeapSort(int *a, int size) { Build_Max_Heap(a, size); cout << "建堆結果..."; arr_display(a, size); int num = size; cout << "排序中..." << endl; for(int i = size; i >= 2; -- i) { swap(a[1], a[size]); -- size; Max_Heapify(a, size, 1); cout << "第" << num - size << "步..."; arr_display(a, num); } } int main() { int a[50], size; //size爲輸入規模大小 cout << "輸入元素個數:"; cin >> size; cout << "輸入各個元素:"; for(int i = 1; i <= size; ++ i) cin >> a[i]; cout << "排序開始..." << endl; HeapSort(a, size); }
最後,再次提醒,去看看《算法導論》的第六章,其中的內容很是詳細
還有你們若是有什麼問題,能夠留言...