堆排序的概念
若在輸出堆頂的最小值(最大值)後,使待剩餘n-1個元素的序列又重建成一個堆,則得到n個元素的次小值(次大值),如此反覆,便能得到一個有序序列,這個過程稱之爲堆排序。
要想實現堆排序,主要需實現以下兩點
----由無序堆建成一個堆
----輸出堆頂元素後,調整剩餘元素爲一個新的堆
在這裏主要實現第二點即可,學會了堆調整,建堆也就水到渠成了。
堆調整算法範例(C語言) --大根堆
void HeapAdjust(int R[], int s, int m)//調整爲大根堆
{
int rc = R[s];
int j;
for (j = 2 * s; j <= m; j *= 2)
{
if ((R[j] < R[j+1]) && j<m)
{
++j;
}//較大key的孩子節點
if (rc >= R[j]) break; //已經大於孩子節點,跳出循環
R[s] = R[j];
//printf("R[%d]: %d\n", j, R[j]);
s = j; //rc應該賦值給位置s上面
printf("j: %d\n", j);
printf("s: %d\n", s);
}
R[s] = rc;
printf("R[%d]: %d\n", s, rc);
}
建堆的過程只需要對完全二叉樹的最後一個非葉子節點開始操作即可。
因爲單節點樹必定是一個堆,完全二叉樹的葉子節點也是一個堆。
建堆範例(C語言)
for (i = n / 2; i >= 1; i--)
{
HeapAdjust(R, i, n);
//for (j = 0; j <= 8; j++)
//{
// printf("%d,", R[j]);
//}
//printf("\n");
}
VS2015編譯測試結果如下圖: