最小堆以及最小優先佇列的實現

2021-10-24 22:13:33 字數 1484 閱讀 4363

build_min_heap的實現

最小堆從邏輯上可以理解為乙個完全二叉樹(如圖a所示),最小堆的性質很簡單,即除了根節點以外,所有的節點都要小於其左右子節點,而從物理儲存上看,它是由陣列的形式來儲存的(如圖b所示)。

最小堆可以應用於最小優先佇列的構建以及堆排序演算法的實現,後面我會繼續更新最小優先佇列的實現。

注意:陣列下標是從1開始的。

要如何通過陣列來體現二叉樹的性質呢?我們通過觀察可以發現運用陣列的下標運算可以很容易找到父子節點之間的聯絡:

節點a[i]的父節點下標為i/2(取下界)

節點a[i]的左子節點下標為2i

節點a[i]的右子節點下標為2i+1

要實現最小堆,我們的思路是:自底向上,逐步調整二叉堆。即每次選中乙個a[i]節點,然後將以a[i]節點作為根結點的最大子樹調整為最小堆。因此我們需要實現以下兩個函式:

min_heapify(a,i) #用於維護最小堆的性質

build-min-heap(a)#用於建堆

min_heapity的輸入是陣列a和下標i,其具體功能是將以a[i]作為根結點的子樹調整為最小堆,其實現方法是利用遞迴。

遞迴過程:先從a[i]的左右子節點中選出最小的,記住其下標j,再將a[i]與a[j]交換數值。然後再次呼叫min_heapity函式,以a陣列和下標j作為輸入,繼續將以a[j]為根結點的最大子樹調整為最小堆。

**如下:

void

min_heapity

(node a[n]

,int i)

else min=i;

if(r<=heap_size&&a[r]

.value

.value)min=r;

//若右子節點的值小於當前節點,則更新最小值下標

if(min!=i)

}

t(n)≦t(2n/3)+o(1)

根據主定理求解可以得到上述遞迴式的解為t(n)=o(lg n),即min_heapify的時間複雜度為o(lg n)。

每乙個葉節點都可以看作是只有乙個元素的最小堆,所以我們不用從葉節點開始建堆。根據完全二叉樹的性質我們知道,葉節點的數量為n/2(取下界),所以我們只需要從a[n/2]開始向a[1]不斷建堆即可。

**如下:

void

build_min_heap

(node a[n]

)}

因為每次呼叫min_heapify的時間複雜度是o(lg n),而build_min_heap需要o(n)次這樣的呼叫,故總的時間複雜度為o(nlg n)

優先佇列的實現(最小堆)

定義上浮函式和下浮函式,對每一次加入的新節點,重新維護最小堆 public class priorityminqueue public priorityminqueue 初始化優先佇列 param capacity public priorityminqueue int capacity else ...

最小堆,優先佇列

定義乙個list h crud 查詢 堆頂 最小 h 0 0 替換 heapq.heapreplace heap,key,value 參考鏈結 你打算每天 最多 吃乙個蘋果來保證營養均衡。注意,你可以在這 n 天之後繼續吃蘋果。示例 1 思路 模擬即可,堆中用key,value 儲存,保質期和蘋果個...

最小堆及基於最小堆的最小優先佇列

最小堆具有的性質 最小堆的父親節點比子節點的值小 在最小堆的類中我們定義的函式主要有 維護最小堆 建立最小堆和利用最小堆進行排序 以下是最小堆的定義 ifndef my min heap h define my min heap h include includeusing namespace st...