【演算法4】4.3.6.最小生成樹-Kruskal演算法
阿新 • • 發佈:2022-06-05
Kruskal演算法(又稱克魯斯卡爾演算法)。
其思想是:首先將圖看成是由一個個孤立的頂點組成,然後按邊的權重從小到大處理,將頂點連線起來,
並且要保證選取的邊不會跟已選取的邊構成環,當選出 V - 1 條邊時最小生成樹生成完成。
Kruskal 演算法每次選取出最小的橫切邊(橫切邊就是連線最小生成樹及其補集的邊),是貪心演算法的體現。
Kruskal 演算法實現:
- 使用優先佇列將邊按從小到大的順序彈出
- 使用 union-find 演算法 判斷是否有環產生
- 使用佇列來儲存最小生成樹的邊
/** * 使用克魯斯卡爾演算法找出加權連通圖的最小生成樹 * */ public class KruskalMST implements MST { private Queue<Edge> mst; public KruskalMST(EdgeWeightedGraph G) { mst = new Queue<>(); // 使用優先佇列儲存最小生成樹的邊 MinPQ<Edge> pq = new MinPQ<>(); // 使用優先佇列按邊從小到大順序處理 UnionFind unionFind = new UnionFind(G.V()); // 使用 union-find 演算法檢測是否會產生環 // 將所有邊新增到優先佇列 for (Edge e : G.edges()) { pq.add(e); } // 開始生成最小生成樹 while (!pq.isEmpty() && mst.size() < G.V() - 1) { Edge e = pq.remove(); int v = e.either(); int w = e.other(v); if (unionFind.connected(v, w)) { continue; } mst.add(e); unionFind.union(v, w); } } }
效能分析:Kruskal 演算法一般比 Prim 演算法慢,因為在處理每條邊時除了兩種演算法都要完成優先佇列操作之外,Kruskal 演算法還需要進行一次 union-find
操作。