隨便說說堆 二項堆概念與實現

2022-03-09 11:32:04 字數 2062 閱讀 1698

二項堆其實就是由多棵二項樹構成的森林,每棵樹的根結點構成乙個單鏈表。其鍊錶序列,按照每棵二項樹的度從小到大排列。

依然分析它的五種基本操作:

說說二項樹。

圖為一顆b3:

說說二項堆,二項堆作為乙個二項樹的集合,按照根結點的度數大小從小到大排列,每棵二項樹都滿足堆的性質(以下以最小堆性質為例),同時二項堆裡不能有兩棵或以上具有相同度數的二項樹。

形如:

對每個結點做如下定義: 

1 typedef struct

node bnode, *bheap;

建立新堆只需要分配乙個二項堆的結點。生成乙個堆物件便可。所以時間複雜度為o(1)。 

1 bnode *make_node(int

key)

合併兩個二項堆。時間複雜度為o(logn)

圖示

**實現

1

//合併兩個根節點鍊錶

2 bnode *merge(bheap h1, bheap h2) else

13return

head;14}

1516

//將兩個相鄰的根樹合併

17void

link(bheap child, bheap heap)

2324

//合併

25 bnode *union(bheap h1, bheap h2) else

if (x->key <= nxt_x->key) else

49 nxt_x = x->next;50}

51return

heap;

52 }

有了合併操作,插入操作也就很好實現了,只需要將新加入的結點與原二項堆合併即可。時間複雜度等同於union,為o(logn)

**實現

1 bnode *insert(bheap heap, int

key)

對於二項堆,其最小結點必然在根煉表中,所以只要遍歷一遍根鍊錶就可以找到。根煉表由logn個結點組成,所以時間複雜度為o(logn),如果在其他操作中設定乙個指標反覆更新最小結點位置,那麼時間複雜度可以壓縮至o(1)。

**實現

1 bnode *minimun(bheap heap) 

8return

minn;

9 }

移除最小結點,因為最小結點必然在根煉表中,所以此操作可以:

時間複雜度o(logn)。

圖示

**實現

1

//將子樹們轉換成乙個新的二項堆

2 bnode *transform(bheap heap)

14 heap->next =tail;

15return

heap;16}

1718

//刪除最小堆頂元素

19 bnode *extract_min(bheap heap)

28if (pre) pre->next = minnode->next;

29else heap = minnode->next;

30 heap = union(heap, transform(minnode->child));

31delete

(minnode);

32return

heap;

33 }

半路演算法之二項樹與二項堆

秉承前文。前面提到過針對稀疏圖時,以二項堆來作為最小優先佇列是更為適宜的。這裡記錄一下學習二項堆的過程。二項堆的名字 於二項樹。二項堆是多個二項樹連在了一起。二項樹的名字 於其bn 棵樹的元素個數為2n 且其深度n處恰有2k 個節點,其性質與二項式非常吻合。此外,它還是一種遞迴定義的有序樹。重點依照...

heap的一些實現,二叉堆,左式堆,二項佇列

這裡的堆指的都是二叉堆,為了優先佇列產生 優先佇列,使一些特殊的結點在出隊的時候要優先出來。出隊入隊操作變成了insert和delete 堆是乙個完全二叉樹,除了最後一層,其餘層都是滿的。這樣的話儲存用乙個陣列就可以,任乙個元素位置在i,其左兒子位置是2 i,右兒子位置是2 i 1,父結點是i 2向...

資料結構與演算法 二項佇列與二叉堆的比較

二叉堆確實是入門級的重要資料結構了,而二項佇列也是慢慢要去掌握的一種支援高效合併的優先佇列實現。本文稍作比較,望拋磚引玉。基本操作 insert 平均 deletemin deletemax merge 二項佇列 o 1 o logn o logn 二叉堆 o 1 o logn o n 不難看出,二...