樹(自由樹)、無序樹和有根樹
自由樹就是一個無回路的連通圖(沒有確定根)(在自由樹中選定一頂點做根,則成為一棵通常的樹)。
從根開始,為每個頂點(在樹中通常稱作結點)的孩子規定從左到右的次序,則它就成為一棵有序樹。
在圖的應用中,我們常常需要求給定圖的一個子圖,使該子圖是一棵樹。
生成樹
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算法的時間主要取決於邊數。它較適合於稀疏圖。