演算法 之 堆 建立堆

2021-08-31 06:28:13 字數 2053 閱讀 5998

給出乙個有n個元素的陣列a[1...n],要建立乙個包含這些元素的堆,可以這樣進行:從空的堆開始,不斷插入每乙個元素,直到a完全被轉移到堆中為止。因為插入第j個鍵值用時o(log j),因此用這種方法建立堆疊的時間複雜性是o(n log n)。

我們知道對應於堆h[1...n]的樹的節點可以方便地以自頂向下、從左到右的方式從1到n編碼。在這樣編碼之後,可以用下面的方法,把一棵n個節點的幾乎完全的二叉樹轉換成堆h[1...n]。從最後乙個節點開始(編碼為n的那乙個)到根節點(編碼為1的節點),逐個掃瞄所有的節點,根據需要,每一次將以當前節點為根節點的子樹轉換成堆。

每一棵只有一片葉子的子樹已經是乙個堆,因此葉子被跳過。

當以第i個節點為根的子樹不是堆時,我們就對i進行sift-down運算一邊把它轉換成堆。如此進行下去,使整棵二叉樹符合堆得性質。

上面說明了如何對樹進行運算。直接對輸入的陣列執行同樣的過程是相當容易的。

令a[1...n]是已知陣列,t是對應於a的一棵幾乎完全的二叉樹,我們注意到 a[⌊

n/2⌋

+1],a[⌊

n/2⌋

+2],...,a[n] 它們對應於t的葉子,這樣我們可以直接從a[⌊

n/2⌋

]開始調整陣列,然後繼續調整 a[⌊

n/2⌋

-1],a[⌊

n/2⌋

-2],...,a[1]。這樣得到的陣列就是我們需要的堆。

過程  makeheap

輸入  n個元素的陣列a[1...n]

輸出  a[1...n]轉換成堆

演算法描述

fori ← ⌊

n/2⌋

downto1

sift-down(a, i)

endfor

注意這裡演算法描述的陣列的索引都是1...n,而不是大家習慣的0...n-1。

下面我們來計算演算法makeheap的執行時間

設t是對應於陣列a[1...n]的一棵幾乎完全的二叉樹,那麼由觀察結論可知,t的高是k=⌊log n

⌋。令a[j]對應該樹的第i層中第j個節點,當語句sift-down(a, j)呼叫過程sift-down時,重複執行的次數最多是k-i。

因為在第i層上正好有2i個節點,0≤i<k,所以每一層迴圈執行的總次數的上界是 (k-i)2i。

總的迴圈執行的總次數的上界就是:

由於在過程sift-down的每乙個迴圈中,最多有兩次元素的比較,因此元素比較的總次數是2×2n=4n。

但是在每次呼叫sift-down時,都至少執行一次迴圈,因此元素比較的最小次數是2⌊

n/2⌋

≥n-1,這個就是元素比較的總次數的下界。

因此,makeheap演算法需要θ(n)時間來構造乙個n元素的堆,似乎並不是之前我們認為的o(n log n)時間。

int* makeheap(int* array, int arraylength)

for (int i = heaplength / 2; i >= 1; i--)

return heap;

}

我使用的陣列是這樣定義的:

const int array_length = 10;  

int array[array_length] = ;

// 如果用我上面寫的方法建立堆,不要忘了在操作完成之後釋放記憶體哦

int* heap = makeheap(array, array_length);

// do something ...

free(heap);

演算法 之 堆 - 簡介

演算法 之 堆 - sift-up和sift-down

演算法 之 堆 - 插入和刪除

堆python 建立堆 python

建立最大 小 堆 二叉堆本質上是一種完全二叉樹,儲存方式並不是鏈式儲存,而是順序儲存 堆操作 插入 葉子節點上調 刪除 堆頂元素下沉 堆建立 非葉子節點下沉 從最後乙個非葉子節點開始 最小堆 最小堆任何乙個父節點的值,都小於等於它左右孩子節點的值 建立過程 如果非葉子節點值大於其子節點,將其下沉 最...

演算法 之 堆 小結

之前我們討論的堆,都把最大鍵值儲存在根節點中,這種型別的堆可以看作是最大堆。我們還可以建立另一種堆,把最鍵小值儲存在根節點中,根節點以外的節點的鍵值,大於或等於儲存在它父節點中的鍵值,這種型別的堆可以看作是最小堆。具體是用最大堆還是最小堆,就根據我們自身的需要來選擇了。堆的演算法到這裡就講完了,下面...

堆 大根堆和小根堆的建立

堆是一種經過排序的完全二叉樹,其中任一非終端節點的資料值均不大於 或不小於 其左孩子和右孩子節點的值。1 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆。1 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆。用堆的關鍵部分是兩個操作 1 put操作 即往堆...