1. 程式人生 > >程式設計師必須掌握的十種演算法---堆排序演算法

程式設計師必須掌握的十種演算法---堆排序演算法

堆排序,就是利用完全二叉樹的某些特性對陣列進行排序。

#include<stdio.h>
int h[101];//用來存放堆的陣列
int n;//用來儲存堆中元素的個數,也就是堆的大小

//交換函式,用來交換堆中兩個元素的值
void swap(int x,int y)
{
    int t;
    t=h[x];
    h[x]=h[y];
    h[y]=t;
}

//向下調整函式
//傳入一個需要向下調整的結點編號i,
//這裡傳入1,是從堆的頂點開始向下調整
void siftdown(int i)
{
    int t,flag=0;//flag用來標記是否需要繼續向下調整

    //當i結點有兒子(其實是至少有左兒子),並且有需要繼續調整的時候迴圈
while(i*2<=n&&flag==0) { //首先判斷它和左兒子的關係,並用t記錄值較大的結點編號 if(h[i]<h[i*2]) t=i*2; else t=i; //如果有右兒子,再對右兒子進行討論 if(i*2+1<=n) { //如果右兒子值更小,更新較大的結點編號 if(h[i]<h[i*2+1]) t=i*2+1
; } //如果發現最大的結點編號不是自己,說明子節點中有比父節點更大的 if(t!=i) { swap(t,i);//交換他們 i=t;//更新i為剛才與它交換的兒子結點的編號,便於接下來繼續向下調整 } else flag=1;//說明當前結點比兩個子節點都要大,不需要在進行調整了 } } //建立堆的函式 void creat() { int i; //從最後一個非葉結點到第一個結點依次向上調整 for(i=n/2
;i>=1;i--) { siftdown(i); } } //堆排序 void heapsort() { while(n>1) { swap(1,n); n--; siftdown(1); } } int main() { int i,num; //讀入要排序的數字的個數 scanf("%d",&num); for(i=1;i<=num;i++) scanf("%d",&h[i]); n=num; //建堆 creat(); //堆排序 heapsort(); //輸出 for(i=1;i<=num;i++) printf("%d ",h[i]); getchar(); getchar(); return 0; }

以上程式碼參考《啊哈!演算法》這本書,如果想更仔細的瞭解這些內容,推薦大家去看這本書。