基本思想:先將待排序資料化為完全二叉樹,從length/2+1處開始尋找他的左/右子節點,將較大值與父節點進行交換,最後遍歷到根節點處,此時根節點為所有數中的最大值,將該值與最後乙個元素進行交換,length=length-1,又從父節點開始進行比較,繼續尋找較大值。將找到的較大值與length-2處進行交換。依次類推。
1.首先將待排序的陣列元素轉換為完全二叉樹,根節點對於陣列第乙個元素,按先序遍歷進行排序,即根節點,左子節點,右子節點。
2.待排序陣列長度為length=8,首先進行堆的初始化,定義乙個for迴圈for(i=length/2-1;i>0;i--)。i首先等於8/2-1=3;因此從a[3]處作為父節點,尋找比它大的左右子節點。此時6作為父節點,3作為左子節點,6沒有右子節點,6是最大值因此不需要進行交換。進入下一輪for迴圈
3.i此時等於2。因此a[2]處作為父節點,它的左子節點右子節點分別為6和1,6比4大,此時最大值位置max=2*2+1處,1比4小,max位置仍為2*2+1處,因此交換a[2]與a[2*2+1]處的元素。交換完成後a[5]作為父節點繼續尋找它的左右子節點,此時a[5]已經為葉子節點,沒有子節點,因此該輪迴圈結束。
4.i此時等於1。因此a[1]處作為父節點,它的左子節點右子節點分別為6和7,5<6,max位置為3處。5<7,max位置變為4。因此交換a[1]與a[max]處的元素。交換後5變為右子節點,此時5已經是葉子節點因此不需要進行繼續尋找子節點,該輪迴圈結束。
5.i此時等於0。因此a[0]處作為父節點,它的左子節點右子節點分別為7和6,7<12,6<12,max位置為0。此輪迴圈結束,i變為-1迴圈結束。此時父節點為陣列中的最大值。
6.進入另外乙個迴圈for(i = len - 1; i >=0; i--),該迴圈將棧頂元素與最後乙個元素進行交換。i=7,將a[0]與a[7]進行交換。
7.此時又從棧頂開始,a[0]作為父節點,比較左右子節點。7>3,max=1。交換a[1]和a[0]。
7.交換的元素a[1]不是葉子節點,需要繼續迭代進行交換。保證交換的元素比它子節點大。因此將a[1]與a[3]進行交換。12作為最大元素不在參與上面的交換。此時7作為最大值位於父節點處。
8.將該迴圈將棧頂元素與最後乙個元素進行交換。此時最後乙個元素為a[length-2]。即7與1進行交換。
9.交換後i=length-1;又從a[0]開始繼續迭代比較。將1和左子節點的6進行交換。交換後繼續將1作為父節點和它的右子節點5進行交換。
10.當i<0時,排序完成。
**:
//list:待調整的陣列 index:待調整的節點下標 len:陣列長度
void heapadjust(int list, int index, int len)
//右子節點大於父節點
if (rchildlist[max])
if (max!=index) }
//初始化堆,大頂堆,從小到大
void heapsort(int list, int len)
//交換堆頂元素和最後乙個元素
for (int i = len - 1; i >=0; i--) }
int main()
; heapsort(list, sizeof(list) / sizeof(int));
for (int i = 0; i < sizeof(list) / sizeof(int); i++)
}
堆排序是一種不穩定的排序方法,最好、最壞、平均時間複雜度: 常見的排序演算法 堆排序
堆是一種特殊的樹形結構,其每個節點都有乙個值,通常的堆指的是一顆完全二叉樹,根的節點大於 或小於 兩個子節點的值,而堆排序是一種樹形選擇排序,在排序過程中將a 0 n 看做是完全二叉樹的順序儲存結構,利用完全二叉樹中父節點與子節點的內在關係來選擇最小的元素或者最大的元素。堆分為大頂堆和小頂堆,父節點...
常見排序演算法之堆排序
1.簡介 堆排序是指利用堆這種資料結構所設計的一種排序演算法。2.堆排序中大堆和小堆 大堆 根節點比子節點大 小堆 跟節點比子節點小 3.核心思想 採用大堆的資料結構為例子。陣列轉完全二叉樹,再把這個完全二叉樹構成乙個大堆,將堆頂根節點和末尾節點互換。把剩下的n 1個元素重新構造成大頂堆 最大值已經...
排序演算法 堆排序
1 什麼是堆 首先它是一顆完全二叉樹,並且父結點的值大於子節點的值 最大堆 或父結點的值小於子結點的值 最小堆 小根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆,又稱最小堆。大根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆,又稱最大堆。2 堆...