最小生成树之kruskal算法概念与实现

概念

最小生成树的kruskal算法非常简单了,原理和prim算法差不多,然而kruskal并不是从源点开始层次考察的,而是直接用优先队列存储所有边,通过贪心算法的思想,用权重最小的边组成最小生成树。需要注意的是要通过并查集过滤掉组成环的边。

实现

/**
 * 最小生成树,克鲁斯卡尔算法
 * @author yuli
 *
 */
public class KruskalMst {
    private LinkedList<Edge> mst;//最小生成树
    public KruskalMst(EdgeWeightedUnGraph graph) {
        mst = new LinkedList<>();
        //使用优先队列来存放边集
        PriorityQueue<Edge> queue = new PriorityQueue<>();
        //得到边集并加入优先队列
        Iterable<Edge> edges = graph.edges();
        for (Edge edge : edges) {
            queue.offer(edge);
        }
        //初始化并查集,用来判断加入边后是否会形成环
        FastUnionFind uf = new FastUnionFind(graph.getV());
        //如果队列为空,或者优先队列小于图的顶点-1(边已经找完了)
        while(!queue.isEmpty() && mst.size() < graph.getV()-1){
            //出队权重最小的
            Edge edge = queue.poll();
            //获得两个顶点
            int v = edge.getV();
            int w = edge.getW();
            //判断是否会形成环,如果形成环就跳过
            if(uf.isConnected(v, w)){
                continue;
            }
            //连通这两个顶点
            uf.union(v, w);
            mst.add(edge);
        }
    }
    /**
     * 获取最小生成树
     * @return
     */
    public Iterable<Edge> edges(){
        return mst;
    }
    /**
     * 获取最小生成树的权重
     * @return
     */
    public double weight(){
        double weight = 0;
        Iterable<Edge> edges = edges();
        for (Edge edge : edges) {
            weight += edge.getWeight();
        }
        return weight;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值