詳解陣列實現隱式二叉堆及堆排序

2021-08-13 23:37:27 字數 1298 閱讀 7231

一,堆的性質

1.頂部總是儲存著最小或者最大的元素

2.有彈出操作,插入操作,合併操作,並且無論進行什麼操作,都保持堆的性質1不變。

二,堆的實現

我用的是陣列來實現隱式二叉堆,陣列實現的二叉堆主要的是二叉堆的節點到陣列下標的對映。比如堆中的第 i 個節點,對應陣列下標也為i,然後通過下標的對映來找父節點,左兒子,右兒子。父節點的下標為i/2,左兒子為2i,右兒子為2i+1

三,堆最重要的乙個性質是能夠保持性質不變,也就是說我們需要維護堆的性質,對於用陣列表示的二叉堆,給定任意索引 i 的節點,我們檢查它的兩個子節點,判斷是否符合堆的性質,不符合就交換,使它符合堆的性質,這種維護的演算法,是基於兩個子樹是合法堆的條件的

//最小堆的維護演算法示例

void heapify(int

*a, int i ,int

size)

else

return;//如果父節點是最小節點,說明堆的性質正確

}}

如果是維護最大堆的性質,只要將數值比較那一部分修改一下就可以了。

三,堆的構造

我們可以用heapify演算法從任意陣列構造堆,相當於維護乙個完全無序的堆,這樣我們就不能自頂向下來修正堆的構造了,而要從下至上修正。由於堆的葉子節點沒有子節點,所以它們是視為符合堆的性質的,所以從最後乙個有分支的節點開始修正,這個節點是最後乙個節點的父節點,所以索引為n/2,n為陣列長度。

這樣分析,我們可以寫出構造堆的演算法如下:

void build-heap(int

*a,int

size)

四,堆的基本操作

堆的通用定義通常要求我們提供一些基本操作,使使用者可以獲取或者修改資料:

獲取頂部元素

int top(int

*a)

2.彈出堆頂元素

我們需要在移除頂部元素後,通過執行heapify演算法來維護堆的性質。最好的辦法使記錄下陣列的首個元素,然後與最後乙個元素交換,然後用heapify維護堆的性質。

int pop(int

*a,int

size)

這個演算法需要額外的空間複雜度o(n),robert w.floyd給出了乙個原地排序,無需建立額外陣列的方法:

void great-heap-sort(int

*a,int

size)

}

二叉堆和堆排序

二叉 堆是乙個陣列,它可以近似看作完全二叉樹。樹上的每乙個節點對應陣列中的乙個元素。除了最底層,該樹是完全充滿的,而且是從左向右填充。根據節點下標可以求出對應的子樹和雙親 parent i return i 2 i表示陣列中的第幾個元素,i 2 表示取整數 left i return 2 i rig...

二叉堆和堆排序的python實現

二叉堆本質上是一種完全二叉數 二叉堆建立 根據原陣列,然後從最後乙個非葉子節點開始,依次下沉,得到最後序列 二叉堆操作 圖比較麻煩就不畫了,可以參考這篇文章 二叉堆 1.二叉堆實現 儲存方式 利用陣列順序儲存 定位方法 利用陣列下標進行定位 父節點parent,左子樹 2 parent 1,右子樹 ...

陣列實現二叉堆

二叉堆的定義 二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 當父結點的鍵值總是大於或等於任何乙個子節點的鍵值時為最大堆。當父結點的鍵值總是小於或等於任何乙個...