暖 墟 二叉堆 大根堆的常見操作

2021-08-21 15:01:27 字數 2033 閱讀 9432

二叉堆使用完全二叉樹(其前n-1層必須被填滿,第n層也要從左到右順序填滿)來實現。

在二叉堆中,所有非終端結點的值均不大於(或不小於)其左右孩子的值。

非終端結點的值均不大於其左右孩子結點的值,這樣的二叉堆叫做小根堆(下圖b),

小根堆根結點的值是該堆中所有結點的最小值;

同樣的,若非終端結點的值都不小於其左右孩子的值,這樣的堆叫做大根堆(下圖a),

大根堆根結點的值為改堆所有結點的最大值。利用堆的此性質,可以實現堆排序。

說明:小根堆和大根堆的實現沒有太大的區別,所以下面以大根堆為例。

堆一般使用陣列來構建,假設為陣列a,結點通常儲存在a[1],

這樣對於下標為k的結點a[k]來說,其左孩子的下標為2*k,右孩子的下標為2*k+1

結點插入的位置應該是完全二叉樹的最後乙個位置(如下圖所示),

對於大根堆來講,需要滿足兩個性質:

(1)堆為完全二叉樹;(2)堆中每個父結點的值都不小於其左右子結點的值。

插入結點可能會破壞這兩條性質,所以在插入結點後需要對堆進行調整。

調整方法為:將插入的結點與其父結點比較,若大於其父結點的值,則交換兩者。

重複此操作,直至該結點不比其父結點大,或者該結點成為根結點。

可以通過插入結點到乙個已經存在的堆中,也可以通過不斷插入結點來構建乙個堆

else break; //找到位置,退出迴圈

}}void insert(int val)

↓↓↓gettop:返回堆頂權值

//gettop

int gettop()

刪除堆頂元素(根結點)後,會得到左右兩棵子樹,此時將堆中最後乙個元素移到堆頂

然後自上而下調整,將該結點與左右孩子結點比較,此時會有三種情況:

(1)結點的左右孩子均為空,此時調整結束

(2)結點只有左孩子,將該結點與左比較。若結點小於其左孩子,則兩者交換,否則調整結束;

(3)結點左右孩子都非空,則將該結點與左右較小者比較,若小於則交換,否則調整結束;

重複此過程,直到該結點不小於其左右孩子結點,或者該結點為葉子結點。

//extract

//刪除堆頂元素,將末尾元素放到堆頂位置,再調整

void down(int p)

else break;

}}void extract()

//remove(p)

void up(int p)

else break; //找到位置,退出迴圈

}}void down(int p)

else break;

}}void remove(int p)

priority_queue實現了乙個大根堆。

支援 push(i),top(),pop()操作,不支援 remove 操作。

priority_queue*** 大根堆

priority_queue, greater> ***x 小根堆

——時間劃過風的軌跡,那個少年,還在等你。

二叉堆相關整理(大根堆小根堆)

二叉堆是一種支援插入 刪除 查詢最值的陣列結構。它其實是一棵滿足堆性質的完全二叉樹,樹上的每乙個節點都帶有乙個權值。層次序列儲存方式,直接用乙個陣列來儲存二叉堆。逐層從左到右為樹中的節點依次編號,把此編號作為節點在陣列中儲存的位置 下標 在這種儲存方式中,父節點編號等於子節點等於子節點編號除以2,左...

python實現二叉堆中的大頂堆 大根堆

堆 英語 heap 是電腦科學中一類特殊的資料結構的統稱。堆通常是乙個可以被看做一棵樹的陣列物件。堆總是滿足下列性質 將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。常見的堆有二叉堆 斐波那契堆等。他們的時間複雜度如下 0 先置為零,只要經過一次swap函式,就再次置為1 in...

(二叉)堆操作

堆操作 實驗目的 一 建堆 將陣列a 1.n 變成乙個最大堆。二 堆排序 將乙個堆中的元素按遞減排序輸出。三 用插入方法建堆 堆大小從1到n每次插入乙個元素到堆中,直到n個元素入堆。實驗原理 二叉 堆是乙個陣列,它可以被看成乙個近似的完全二叉樹。樹上的每乙個結點對應陣列中的乙個元素。除了最底層外,該...