代碼
#include <stdio.h>
#include <stdlib.h>
void HeapSort(int num[],int size);
void BuildHeap(int num[] ,int size);
void PercolateDown(int num[] , int index,int size);
void PrintHeap(const char* strMsg,int array[],int nLength);
void Swap(int num[] , int v, int u);
int main(int argc, char *argv[])
{
/* 將數組看成完全二叉樹的前序走訪結果的線性儲存 */
int data[13]={8,5,4,6,13,7,2,9,12,11,3,10,1};
HeapSort(data,13);
system("PAUSE");
return 0;
}
void HeapSort(int num[] ,int size)
{
int i;
int iLength=size;
PrintHeap("Befor Sort:",num,iLength);
BuildHeap(num,size);// 建立小頂堆
for (i = iLength - 1; i >= 1; i--) {
Swap(num, 0, i);// 將選出的最小值交換至位置i,並將索引i處設為有序區
size--;// 每交換一次讓規模減少一次(無序區的範圍逐步縮小)
PercolateDown(num, 0,size);// 將新的首元素下濾操作
PrintHeap("Sort Heap:",num,iLength);
}
}
/* 建堆方法,只需線性時間建好;
建堆的結果:數組的第一個元素(即樹根)是所有元素中的最小值,索引小於等於size/2-1的其它元素(即其它非葉子節點)的值都是其所在子樹的最小值 */
void BuildHeap(int num[] ,int size) {
int i;
//從最後一個非葉子節點開始,對每個非葉子節點進型最小根調整,保證每個根節點都是其子樹中的最小值。相當於從最底層的父節點開始逐個調整。
for (i = size / 2 - 1; i >= 0; i--) {
PercolateDown(num, i,size);// 進行下濾操作
PrintHeap("Build heap:",num,size);
}
}
/* 對該數進行下濾操作,直到該數比左右節點都小就停止下濾。
即對某個根節點的值進行位置下降調整,使該值比其左右子節點都小;
若該節點是葉子節點,則無法while迴圈 */
void PercolateDown(int num[] , int index,int size) {
int min;// 設定最小指向下標
while (index * 2 + 1<size) {// 如果該數有左節點,則假設左節點最小
min = index * 2 + 1;// 擷取左節點的下標
if (index * 2 + 2<size) {// 如果該數還有右節點
if (num[min] > num[index * 2 + 2]) {// 就和左節點分出最小者
min = index * 2 + 2;// 此時右節點更小,則更新min的指向下標
}
}
// 此時進行該數和最小者進行比較,
if (num[index] < num[min]) {// 如果index最小,
break;// 停止下濾操作
} else {
Swap(num, index, min);// 交換兩個數,讓大數往下沉
index = min;// 更新index的指向
}
}// while
}
// 給定數組交換兩個數的位置
void Swap(int num[] , int v, int u) {
int temp = num[v];
num[v] = num[u];
num[u] = temp;
}
void PrintHeap(const char* strMsg,int array[],int nLength)
{
int i;
printf("%s",strMsg);
for(i=0;i<nLength;i++)
{
printf("%d ",array[i]);
}
printf("\n");
}
修改自以下連結:http://www.javaeye.com/topic/604856