首先給出堆的定義(這裡**
n個元素的序列當且僅當滿足下列關係之一時,稱之為堆。
情形1:
情形2:
其中i=1,2,…,n/2向下取整;
這邊兩個定義是由序號從0開始取還是從1開始取決定的。
說明一下定義的意思,因為堆是完全二叉樹(官方定義是:若設二叉樹的深度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹),其實很簡單即只有最後一層可以不全,其他各層節點都是滿的,而且就算最後一層不全,也不能出現只有右孩子而沒有左孩子的情況,即所有結點都連續集中在最左邊。
而且二叉樹的序列化即寫成陣列形式用的是層遍歷,因此有個很好的性質即第i個節點的左右孩子序號分別為2i和2i+1,而且最後乙個有孩子的節點序號為n/2,n為節點個數。(這裡序號從1開始)
因此在構建大根堆的時候我們可以從最後乙個有孩子的節點序號開始向前遍歷,如果該節點比它的孩子小就交換(只需要考慮當前節點和他的孩子)。
而堆排序很巧妙,首先構建好大根堆,然後我們拿出頭節點和最後乙個節點交換,因為頭節點一定是最大的,所以現在已經將最大的值放入陣列最後了,然後使用除了最後乙個元素的陣列再次構建大根堆,這樣迴圈下來就可以將陣列排序。**如下:
#includeusing namespace std;
class heapsort
}void heapadjust(int *a,int s,int m)
//已知a[s,...,m]中記錄的關鍵字除a[s]之外均滿足堆的定義,本函式調整a[s]
//的關鍵字,使a[s,...,m]成為乙個大頂堆(對其中記錄的關鍵字而言)
a[s]=rc;
}};int main()
; heapsort a;
a.heapsort(arr,13);
for(int i=0;i<13;i++)
cout<
堆及堆排序
什麼是堆?堆是一棵完全二叉樹,並滿足 n od ei n ode2 i 1 andn odei n ode2 i 2 node quad and quad node i node nodei n ode2 i 1 and node i n ode2 i 2 大頂堆 或者nod ei n ode2 i...
堆及堆排序
堆是一種特殊的資料結構,它是完全二叉樹,可以用一維陣列來儲存,因為二叉樹的性質,所以根據陣列下標就可以確定位置,下面 是關於堆的實現,刪除的過程其實就是將堆的根節點取出的過程,這時的順序就是有序的,如果是最小堆,那麼就是從小到大排序,反之,就是從大到小 1 include 2 3int h 101 ...
堆的實現及堆排序
前兩天刷筆試題,判斷乙個陣列的序列可以構成堆。仔細想了想,腦海裡幾乎已經遺忘了堆的知識,今天又重新去看書,把堆的知識總結一下。首先堆是一種陣列物件,它可以被看成乙個完全二叉樹。在我們常見的堆中有大堆和小堆。對大堆來說,每個父節點都大於孩子結點 小堆恰好相反。而且,大堆 小堆的每個子樹也是乙個大堆 小...