樹(自由樹)、無序樹和有根樹
自由樹就是一個無迴路的連通圖(沒有確定根)(在自由樹中選定一頂點做根,則成為一棵通常的樹)。
從根開始,為每個頂點(在樹中通常稱作結點)的孩子規定從左至右的次序,則它就成為一棵有序樹。
在圖的應用中,我們常常需要求給定圖的一個子圖,使該子圖是一棵樹。
產生樹
1、產生樹
如果連通圖G的一個子圖是一棵包含G的所有頂點的樹,則該子圖稱為G的產生樹(SpanningTree)。
產生樹是連通圖的包含圖中的所有頂點的極小連通子圖。
圖的產生樹不惟一。從不同的頂點出發進行遍曆,可以得到不同的產生樹。
2、深度優先產生樹和廣度優先產生樹
(1)產生樹的求解方法
設圖G=(V,E)是一個具有n個頂點的連通圖。則從G的任一頂點(源點)出發,作一次深度優先搜尋(廣度優先搜尋),搜尋到的n個頂點和搜尋過程中從一個已訪問過的頂點vi搜尋到一個未曾訪問過的鄰接點vj,所經過的邊(vi,vj)(共n-1條)組成的極小連通子圖就是產生樹。(源點是產生樹的根)
通常,由深度優先搜尋得到的產生樹稱為深度優先產生樹,簡稱為DFS產生樹;由廣度優先搜尋得到的產生樹稱為廣度優先產生樹,簡稱為BPS產生樹。
(2)求DFS產生樹和BFS產生樹演算法
只要在DFS(或DFSM)演算法的if語句中,在遞迴調用語句之前加入適當產生邊(vi,vj)的操作(如將該邊輸出或儲存),即可得到求DFS產生樹的演算法。
在BFS(或BFSM)演算法的if語句中,加入產生樹邊(vi,vj)的操作,可得到求BFS產生樹的演算法。【參見練習】
注意:
①圖的廣度優先產生樹的樹高不會超過該圖其它產生樹的高度
②圖的產生樹不惟一,從不同的頂點出發進行遍曆,可以得到不同的產生樹。
3、產生樹的通用定義
若從圖的某頂點出發,可以系統地訪問到圖中所有頂點,則遍曆時經過的邊和圖的所有頂點所構成的子圖,稱作該圖的產生樹。(此定義不僅僅適用於無向圖,對有向圖同樣適用。)
(1)若G是強連通的有向圖,則從其中任一頂點v出發,都可以訪問遍G中的所有頂點,從而得到以v為根的產生樹。
(2)若G是有根的有向圖,設根為v,則從根v出發可以完成對G的遍曆,得到G的以v為根的產生樹。
(3)若G是非連通的無向圖,則要若干次從外部調用DFS(或BFS)演算法,才能完成對G的遍曆。每一次外部調用,只能訪問到G的一個連通分量的頂點集,這些頂點和遍曆時所經過的邊構成了該連通分量的一棵DFS(或BPS)產生樹。G的各個連通分量的DFS(或BFS)產生樹組成了G的DFS(或BFS)產生森林。
(4)若G是非強連通的有向圖,且源點又不是有向圖的根,則遍曆時一般也只能得到該有向圖的產生森林。
5、普裡姆(Prim)演算法
(1)演算法思想
T=(U,TE)是存放MST的集合。
①T的初值是({r},¢)
即最小產生樹初始時只有一個紅點r,沒有紅邊。
②T經過n-1次如下步驟操作,最後得到一棵含n個頂點,n-1條邊的最小產生樹
⒈選擇紫邊集中一條輕邊並擴充進T
⒉將輕邊串連的藍點改紅點
⒊將輕邊改紅邊
⒋修改紫邊集
(2)較小紫邊集的構造
若當前形成的T中有k個頂點,|U|=k,|V-u|=n-k,故可能的紫邊數目是k(n-k)。從如此大的紫邊集中選擇輕邊是低效的。因此,必須構造較小的紫邊集。
對於每個藍點v ∈V-U,從v到各紅點的紫邊中,只有最短的那一條才有可能是輕邊。因此,只須保留所有n-k個藍點所關聯的最短紫邊作為輕邊的候選集即可。
(3)候選紫邊集合的修改
當把輕邊(u,v)擴充到T時,因為v由藍變紅,故對每個剩餘的藍點j,邊(v,j)就由非紫邊變為紫邊,這條新紫邊的長度可能小於藍點j原來所關聯的最短紫邊的長度。因此,用長度更小的新紫邊取代那些原有的最短紫邊。
(4)Prim演算法的虛擬碼描述
PrimMST(G,T,r){
//求圖G的以r為根的MST,結果放在T=(U,TE)中
InitCandidateSet(…);//初始化:設定初始的輕邊候選集,共置T=({r},¢)
for(k=0;k<n-1;k++){ //求T的n-1條樹邊
(u,v)=SelectLiShtEdge(…);//選取輕邊(u,v);
T←T∪{(u,v)};//擴充T,即(u,v)塗紅加入TE,藍點v並人紅點集U
ModifyCandidateSet(…); //根據新紅點v調整候選輕邊集
}
}
(5) 演算法的執行過程
用PRIM演算法得到最小產生樹的過程【參見動畫示範】
注意:
若候選輕邊集中的輕邊不止一條,可任選其中的一條擴充到T中。
連通網的最小產生樹不一定是惟一的,但它們的權相等。
(6)演算法特點
該演算法的特點是當前形成的集合T始終是一棵樹。將T中U和TE分別看作紅點和紅邊集,V-U看作藍點集。演算法的每一步均是在串連紅、藍點集的紫邊中選擇一條輕邊擴充進T中。MST性質保證了此邊是安全的。T從任意的根r開始,並逐漸生長直至U=V,即T包含了 C中所有的頂點為止。MST性質確保此時的T是G的一棵MST。因為每次添加的邊是使樹中的權儘可能小,因此這是一種"貪心"的策略。
(7)演算法分析
該演算法的時間複雜度為O(n2)。與圖中邊數無關,該演算法適合於稠密圖。
(1)演算法思想
①T的初始狀態
只有n個頂點而無邊的森林T=(V,¢ )
②按邊長遞增的順序選擇E中的n-1安全邊(u,v)並加入T,產生MST
注意:
安全邊指兩個端點分別是森林T裡兩棵樹中的頂點的邊。加入安全邊,可將森林中的兩棵樹串連成一棵更大的樹
因為每一次添加到T中的邊均是當前權值最小的安全邊,MST性質也能保證最終的T是一棵最小產生樹。
(2)演算法特點
該演算法的特點是:當前形成的集合T除最後的結果外,始終是一個森林。
(3)Kruskal演算法的抽象描述
KruskalMST(G){//求連通網G的一棵MST
T=(V,¢); //初始化,T是只含n個頂點不包含邊的森林
依權值的遞增序對E(G)中的邊排序,並設結果在E[0..e-1]中
for(i=0;i<e;i++) { //e為圖中邊總數
取E[0..e-1)中的第i條邊(u,v);
if u和v分別屬於T中兩棵不同的樹then
T=T∪{(u,v)};//(u,v)是安全邊,將其加入T中
if T已是一棵產生樹then
`` return T;
}//endfor
return T;
}
(4)用Kruskal演算法構造最小產生樹的過程
用Kruskal演算法構造最小產生樹的過程【參見動畫示範】
(5)演算法分析
該演算法的時間複雜度為O(elge)。
Kruskal演算法的時間主要取決於邊數。它較適合於稀疏圖。