在例1-2及1-3中已考察過這個問題。因為具有n 個頂點的無向網路G的每個產生樹剛好具有n-1條邊,所以問題是用某種方法選擇n-1條邊使它們形成G的最小產生樹。至少可以採用三種不同的貪婪策略來選擇這n-1條邊。這三種求解最小產生樹的貪婪演算法策略是: K r u s k a l演算法,P r i m演算法和S o l l i n演算法。
1.Kruskal演算法
(1) 演算法思想
K r u s k a l演算法每次選擇n- 1條邊,所使用的貪婪準則是:從剩下的邊中選擇一條不會產生環路的具有最小耗費的邊加入已選擇的邊的集合中。注意到所選取的邊若產生環路則不可能形成一棵產生樹。K r u s k a l演算法分e 步,其中e 是網路中邊的數目。按耗費遞增的順序來考慮這e 條邊,每次考慮一條邊。當考慮某條邊時,若將其加入到已選邊的集合中會出現環路,則將其拋棄,否則,將它選入。
考察圖1-12a 中的網路。初始時沒有任何邊被選擇。圖13-12b 顯示了各節點的目前狀態。邊( 1,6)是最先選入的邊,它被加入到欲構建的產生樹中,得到圖1 3-1 2 c。下一步選擇邊( 3,4)並將其加入樹中(如圖1 3-1 2 d所示)。然後考慮邊( 2,7),將它加入樹中並不會產生環路,於是便得到圖1 3-1 2 e。下一步考慮邊( 2,3)並將其加入樹中(如圖1 3-1 2 f所示)。在其餘還未考慮的邊中,(7,4)具有最小耗費,因此先考慮它,將它加入正在建立的樹中會產生環路,所以將其丟棄。此後將邊( 5,4)加入樹中,得到的樹如圖13-12g 所示。下一步考慮邊( 7,5),由於會產生環路,將其丟棄。最後考慮邊( 6,5)並將其加入樹中,產生了一棵產生樹,其耗費為9 9。圖1-1 3給出了K r u s k a l演算法的虛擬碼。
/ /在一個具有n 個頂點的網路中找到一棵最小產生樹
令T為所選邊的集合,初始化T=
令E 為網路中邊的集合
w h i l e(E≠)&&(| T |≠n- 1) {
令(u,v)為E中代價最小的邊 E=E- {(u,v)} / /從E中刪除邊
i f( (u,v)加入T中不會產生環路)將( u,v)加入T
}
i f(| T |==n-1) T是最小耗費產生樹
e l s e 網路不是互連的,不能找到產生樹
圖13-13 Kruskao演算法的虛擬碼