參考資料:http://www.7747.net/kf/201104/88993.html 《大話數據結構》第9章 排序 9.7 堆排序
以上頁面非常詳細以源碼+圖示的方法講述了堆排序的全部過程,在此記錄,僅爲個人學習筆記。
堆排序的基本思想爲:將待排序的序列構造成大頂堆(大頂堆:非葉子節點的兒子均小於父親節點的完全二叉樹(完全二叉樹,最底一層不必滿,不是滿二叉樹)),該堆的根節點爲最大元素,將此元素取出,然後將最後一個元素換至根節點處,再次構造大頂堆,循環至所有元素取出。堆排序的的算法複雜度爲O(nlogn)。
堆排序實現過程中的關鍵有兩點:
1、如何將無序序列建立成大頂堆
首先將無序序列按照原先順序放入完全二叉樹中,然後用HeapAdjust()函數對其進行大頂化。
2、當輸出堆頂元素後,如何將剩餘元素形成新的大頂堆
當最後一個元素移至堆頂後,即可用HeapAdjust()對其大頂化。
代碼如下:
//SqList爲存儲無序序列的隊列
void HeapSort(SqList *L)
{
int i;
for(i = L->length/2; i > 0; i--)
{
//L爲存儲大頂堆的數組,i爲起始節點,L->length爲最後的節點
HeapAdjust(L, i, L->length);
}
for(i = L->length; i > 1; i--)
{
swap(L, 1, i);
HeapAdjust(L, 1, i - 1);
}
}
void HeapAdjust(SqList *L, int s, int m)
{
int temp, j;
temp = L->r[s];
for(j = 2 * s; j <= m; j *= 2)
{
if(j < m && L->r[j] < L->r[j+1])
++j;
if(temp >= L->r[j])
break;
L->r[s] = L->r[j];
s = j;
}
L->r[s] = temp;
}
void swap(SqList *L, int s, int m)
{
printf("%d/n", L->r[s]);
L->r[s] = L->r[m];
}