堆排序練習(Heap Sort

2021-07-10 16:35:17 字數 1640 閱讀 5821

一. 目的以及背景知識

進行堆排序練習,掌握堆的構建與輸出。

堆定義:

對於序列a[1,n],對於任意i都有a[i]>=a[2i],a[i]>=a[2*i+1],則該序列稱為大頂堆或者最大堆。反之則成為最小堆。

堆篩選或堆調整:

從最後乙個葉子結點開始篩選出該節點的兄弟結點與父節點中最大或最小的元素與父節點交換。

建堆演算法證明:

第一步:i=n/2時,i+1,..n都是葉節點,是最簡單的最大堆的根。

第二步:進入迴圈處理,堆演算法維護了i+1,..n都是最大堆的根節點或最大堆的性質。i遞減進行下一次迴圈。

第三部:i=0時,計算終止,每個結點都是符合最大堆性質的節點。演算法證明完畢。

二. 原始碼

建堆原始碼,最大堆與最小堆:

//建立乙個小頂堆。ri<=r2i(左孩子),ri<=r2i+1(右孩子)

void buidingsmallheap(t testarray, int nsize)

}//調整小頂堆

void smallheapadjust(t testarray,int nparent, int nsize)

//選取的最小結點大於頂級父節點,則退出調整過程

if (key<=testarray[j])

testarray[nparent] = testarray[j];//將較大的子節點放在父節點位置

nparent = j;//交換的子節點作為父節點進行下一次的堆調整

}testarray[nparent] = key;//將最後調整的結點位置放置哨兵

}//建立乙個大頂堆。ri>=r2i(左孩子),ri>=r2i+1(右孩子)

void buidingbigheap(t testarray, int nsize)

}//調整大頂堆

void bigheapadjust(t testarray, int nparent, int nsize)

//選取的最大結點小於於頂級父節點,則退出調整過程

if (key >= testarray[j])

testarray[nparent] = testarray[j];//將較大的子節點放在父節點位置

nparent = j;//交換的子節點作為父節點進行下一次的堆調整

}testarray[nparent] = key;//將最後調整的結點位置放置哨兵

}

呼叫**:

int main()

三. 遇到問題

1、最大堆最小堆從數學定義上很清晰,是怎麼一種狀態很模糊。

2、在實際程式設計中下標從0開始,而在定義中下標從1開始,這點在進行父節點子節點位置計算產生了問題。

3、優先建立了最小堆,由於平時都是公升序排序,最小堆在公升序輸出上不具有適用性。

4、想辦法進行最小堆到最大堆的轉換思考,最後發現還不如直接建造最大堆。

5、建堆與輸出都涉及堆調整,分散在多個過程,沒有跟蹤比較與移動次數。

五. 後續計畫

進行交換排序練習。

六. 參考資料

1、演算法導論

2、八大演算法排序

3、建大頂堆和小頂堆及堆排序演算法

4、堆排序 heap sort

排序 堆排序(heapSort)

時間複雜度 o nlog n 空間複雜度 o 1 不穩定 把此序列對應的二維陣列看成乙個完全二叉樹。那麼堆的含義就是 完全二叉樹中任何乙個非葉子節點的值均不大於 或不小於 其左,右孩子節點的值。由上述性質可知大頂堆的堆頂的關鍵字肯定是所有關鍵字中最大的,小頂堆的堆頂的關鍵字是所有關鍵字中最小的。因此...

堆排序(heap sort)總結

以前學資料結構的時候,用的是嚴的書,對於堆這個結構的概念似懂非懂。往往過了一段時間後有不會。現在趁著再次學習資料結構的機會,結合網上的資料整理出自己對堆的理解。二叉堆滿足二個特性 2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 1.堆是完全二叉樹。2.完全二叉樹通常用陣列儲存。3.完...

堆排序(HeapSort)詳解

用法區別 由以上特點我們可以得到堆的特性 將待排序序列,構成乙個大頂堆 此時,最大值為根節點 索引 0 將最大值與末尾元素交換 將剩餘的len 1個元素,繼續構造成乙個大頂堆 重複以上2 3步驟 找到那個 最深 最右 的非葉子節點 從右至左,從上至下構建大頂堆,呼叫adjustheap 方法 adj...