Kruskal算法
第二种最小生成树算法 —— Kruskal算法
按照边的权重顺序(从小到大)处理它们,将边加入最小生成树中,加入的边不会与已经加入的边构成环,直到树中含有
V
−
1
V-1
V−1 条边为止。这些边逐渐由一片森林合并为一棵树,也就是图的最小生成树。
Kruskal算法能够得到任意加权无向图的最小生成树。
算法如下:
使用一条优先队列pq 来将边按照权重排序,一个union-find数据结构uf 来识别会形成环的边,一条队列mst来保存最小生成树的所有边。
/*
* 最小生成树的 Kruskal算法
*/
public class KruskalMST {
private Queue<Edge> mst; //使用一条队列来保存最小生成树的所有边
public KruskalMST(EdgeWeightedGraph G) {
mst = new Queue<Edge>();
MinPQ<Edge> pq = new MinPQ<>(); //使用一条优先队列来保存还未被检查的边
for(Edge e : G.edges())
pq.insert(e);
UF uf = new UF(G.V()); //使用一个union-find数据结构来判断无效的边
while(!pq.isEmpty() && mst.size() < G.V()-1) {
Edge e = pq.delMin(); //从pq得到权重最小的边和它的顶点
int v = e.either(), w=e.other(v);
if(uf.connected(v, w)) //处于同一个连通分量中.忽略失效的边
continue;
uf.union(v, w); //合并分量
mst.enqueue(e); //将边添加到最小生成树中
}
}
public Iterable<Edge> edges() { return mst; }
}