n=0; for(i=1;i<=m;i++) { n++; h[ n]=a[ i]; //或者寫成scanf("%d",&h[ n]); siftup(); }
for(i=n/2;i>=1;i--) siftdown(i);
//刪除最大的元素 int deletemax() { int t; t=h[ 1];//用一個臨時變量記錄堆頂點的值 h[ 1]=h[ n];//將堆得最後一個點賦值到堆頂 n--;//堆的元素減小1 siftdown(1);//向下調整 return t;//返回以前記錄的堆得頂點的最大值 }
#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; } //向下調整函數 void siftdown(int i) //傳入一個須要向下調整的結點編號i,這裏傳入1,即從堆的頂點開始向下調整 { 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[ t] > h[ i*2+1]) t=i*2+1; } //若是發現最小的結點編號不是本身,說明子結點中有比父結點更小的 if(t!=i) { swap(t,i);//交換它們,注意swap函數須要本身來寫 i=t;//更新i爲剛纔與它交換的兒子結點的編號,便於接下來繼續向下調整 } else flag=1;//則否說明當前的父結點已經比兩個子結點都要小了,不須要在進行調整了 } } //創建堆的函數 void creat() { int i; //從最後一個非葉結點到第1個結點依次進行向上調整 for(i=n/2;i>=1;i--) { siftdown(i); } } //刪除最大的元素 int deletemax() { int t; t=h[ 1];//用一個臨時變量記錄堆頂點的值 h[ 1]=h[ n];//將堆得最後一個點賦值到堆頂 n--;//堆的元素減小1 siftdown(1);//向下調整 return t;//返回以前記錄的堆得頂點的最大值 } int main() { int i,num; //讀入數的個數 scanf("%d",&num); for(i=1;i<=num;i++) scanf("%d",&h[ i]); n=num; //建堆 creat(); //刪除頂部元素,連續刪除n次,其實夜就是從大到小把數輸出來 for(i=1;i<=num;i++) printf("%d ",deletemax()); getchar(); getchar(); return 0; }
//堆排序 void heapsort() { while(n>1) { swap(1,n); n--; siftdown(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; } //向下調整函數 void siftdown(int i) //傳入一個須要向下調整的結點編號i,這裏傳入1,即從堆的頂點開始向下調整 { 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[ t] < h[ i*2+1]) t=i*2+1; } //若是發現最大的結點編號不是本身,說明子結點中有比父結點更大的 if(t!=i) { swap(t,i);//交換它們,注意swap函數須要本身來寫 i=t;//更新i爲剛纔與它交換的兒子結點的編號,便於接下來繼續向下調整 } else flag=1;//則否說明當前的父結點已經比兩個子結點都要大了,不須要在進行調整了 } } //創建堆的函數 void creat() { int i; //從最後一個非葉結點到第1個結點依次進行向上調整 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; //讀入n個數 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; }