日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法导论之二项堆

發布時間:2025/4/16 编程问答 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法导论之二项堆 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

每件事物都有其應需而生的目的,既然存在了,一定有其出現的因和果。二項堆的存在,就是因為二叉堆在Union操作上性能不如意而被發明的。二項堆的Union操作只需O(lgn)時間就可以完成兩個二項堆的合并(總共n個元素)。

二叉堆是完全二元樹(二叉樹)或者是近似完全二元樹(二叉樹)。二叉堆有兩種:最大堆和最小堆。最大堆:父結點的鍵值總是大于或等于任何一個子節點的鍵值;最小堆:父結點的鍵值總是小于或等于任何一個子節點的鍵值。

那么二項堆的定義呢?二項堆是由一組二項樹組成,所以先看二項樹定義。

二項樹Bk是一種遞歸定義的有序樹。二項樹B0只包含一個節點。二項樹Bk由兩顆樹Bk-1連接而成:其中一顆樹的根式另一個樹的根的最左孩子。二項樹Bk具有以下性質:

1)共有2k個節點

2)樹的高度為k

3)在深度i處恰有個節點,其中i=0,1,…,k

4)根的度數為k,大于任何其他結點的度數,并且如果根的子女從左到右編號為k-1,k-2,…,1,0,子女i是子樹的Bi根。

二項堆H是由一組二項樹組成,并滿足以下性質:

1)H中的每個二項樹都遵循最小堆性質:結點的關鍵字大于或等于其父節點的關鍵字;

2)對任意非負整數k,在H中至多有一棵二項樹的根具有度數k。

這兩點總結來說,關系到二項堆中二項樹的兩點,一是結點度數,另一個是節點關鍵字值。首先關鍵字值要有序,父結點要小于子結點,其次,二項堆中二項樹的根結點度數要互異(不能有兩棵二項樹的根的度數是一樣)。這是在二項堆操作中一定要守恒的。二項堆中結點的域有:指向父節點的指針p[x]、指向最左孩子的指針child[x]、指向緊右兄弟的指針sibling[x]、結點度數degree[x]、關鍵字值key[x]。

二項堆操作,如創建、查找最小關鍵字、刪除關鍵字等都要維持其性質,其中合并兩個二項堆需要重點說明其算法和性能。

Fun_Binominal_heap_Union(H1,H2){

??? Make_Binominal_Heap(H);//建一個新堆

??? head[H]=Binominal_Heap_Merge(H1,H2);//合并成一個按度數遞增次序排列的鏈表,堆的根按照度數遞增作為新堆的根

??? if head[H]=null then return H;

??? prev[x]=null;

??? x=head[H];

??? next[x]=sibling[x];//第一棵樹根作為第一個結點

??? while next[x] is not null

??????? do if (degree[x] ≠degree[next[x]]

or(sibling[next[x]] is not null and degree[x]=dgree[sibling[next[x]]]

thenprev[x]=x?

???? x=next[x]

??????????? else if key[x] =< key[next[x]]

???????????????? thensibling[x]=sibling[next[x]]

????????????????????? Binoial_link(next[x],x);

??????????? else if prev[x]=null

??????????????? then head[H]=next[x]

??????????????? else sibling[prev[x]]=next[x]

??????????????? ?????Binoial_link(x,next[x]);

???????????????????? x=next[x];

??????????? next[x]=sibling[x];

??????? return H;

}

函數內,主要是對合并后結點做處理,以確保滿足二項堆和二項樹性質,可以看到主要對結點的比較就是度數和關鍵字值。看下兩個度數相同的二項樹Bk-1合并成一顆樹Bk的函數。

Fun_ Binoial_link(x,y){

??? p[y]=x; //x作為y的父結點

??? sibling[y]=child[x];//x的孩子成為y的兄弟

??? child[x]=y;

??? degree[x]=degree[x]+1;

}

Binominal_heap_Union函數運行時間是O(lgn),其中n是二項堆H1(n1)和H2(n2)中總的結點數。H1至多包含lgn1+1個根,H2至多包含lgn2+1個根,合并后H至多包含2lgn+2,即O(lgn)個根。而執行函數的時間主要是在根結點循環,所以總共至多執行lgn2+2次迭代。

比較有趣的一個操作是當關鍵字值減少時調整二項堆使其保持性質,也是需要O(lgn)運行時間,要去判斷關鍵字值。那么能否先刪除關鍵字再作為新的關鍵字插入呢?新關鍵字插入導論中沒有給出,但我想可以作為堆合并來處理,因為一個結點就是一顆二項樹或二項堆,所以時間也是O(lgn),但刪除關鍵字的時間也需要O(lgn),總共需要O(2lgn)次,所以還是直接在原來結點調整值,然后保持二項堆性質。

雖然理解了定義和基本操作,但二項堆還沒想到具體應用點。

總結

以上是生活随笔為你收集整理的算法导论之二项堆的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。