最小生成树-Kruskal算法

来源:互联网 发布:淘宝删除邀请我的回答 编辑:程序博客网 时间:2024/06/14 06:28

kruskal算法即克鲁斯卡尔算法,指求加权连通图的最小生成树的算法。kruskal算法总共选择n- 1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。注意到所选取的边若产生环路则不可能形成一棵生成树。kruskal算法分e步,其中e是网络中边的数目。按耗费递增的顺序来考虑这e条边,每次考虑一条边。当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入。kruskal算法主要应用在计算机、数学(图论)、数据结构中。

package com.gloomy.graph;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.PriorityQueue;import java.util.Set;class Edge implements Comparable<Edge> {    /*     * V、W之间的边长     */    private int edgeLength;    /*     * 边一端的顶点V     */    private Vertex V;    /*     * 边另一端的顶点W     */    private Vertex W;    public Edge(int edgeLength, Vertex v, Vertex w) {        super();        this.edgeLength = edgeLength;        V = v;        W = w;    }    /*     * 自然顺序比较     */    @Override    public int compareTo(Edge o) {        return this.edgeLength - o.edgeLength;    }    public int getEdgeLength() {        return edgeLength;    }    public Vertex getV() {        return V;    }    public Vertex getW() {        return W;    }    public void queueEdgeLength(int edgeLength) {        this.edgeLength = edgeLength;    }    public void queueV(Vertex v) {        V = v;    }    public void queueW(Vertex w) {        W = w;    }}/** * 最小生成树- Kruskal 算法 *  * @author 过路的守望 * */public class KruskalAlgorithm {    private Map<Vertex, Set<Vertex>> map = new HashMap<Vertex, Set<Vertex>>();    public static void main(String[] args) {        /*         * 优先队列最小堆         */        PriorityQueue<Edge> queue = new PriorityQueue<Edge>();        List<Edge> list = new ArrayList<Edge>();        Vertex A = new Vertex("A");        Vertex B = new Vertex("B");        Vertex C = new Vertex("C");        Vertex D = new Vertex("D");        Vertex E = new Vertex("E");        Vertex F = new Vertex("F");        Vertex G = new Vertex("G");        Edge edge1 = new Edge(1, A, D);        Edge edge2 = new Edge(2, A, B);        Edge edge3 = new Edge(4, A, C);        Edge edge4 = new Edge(3, B, D);        Edge edge5 = new Edge(10, B, E);        Edge edge6 = new Edge(2, C, D);        Edge edge7 = new Edge(7, E, D);        Edge edge8 = new Edge(5, C, F);        Edge edge9 = new Edge(1, G, F);        Edge edge10 = new Edge(4, G, D);        Edge edge11 = new Edge(8, F, D);        Edge edge12 = new Edge(6, G, E);        queue.add(edge12);        queue.add(edge11);        queue.add(edge10);        queue.add(edge9);        queue.add(edge8);        queue.add(edge7);        queue.add(edge6);        queue.add(edge5);        queue.add(edge4);        queue.add(edge3);        queue.add(edge2);        queue.add(edge1);        KruskalAlgorithm kruskalAlgorithm = new KruskalAlgorithm();        kruskalAlgorithm.kruskalAlgorithm(queue, 7, list);        int len = 0;        for (Edge edge : list) {            len += edge.getEdgeLength();        }        System.out.println("最短权值:" + len);    }    /**     *      * @param queue     *            边的集合     * @param vertexSize     *            顶点数目     */    private void kruskalAlgorithm(PriorityQueue<Edge> queue, int vertexSize,            List<Edge> list) {        Edge curEdge = null;        /*         * 顶点个数为V的最小生成树有V-1条边,循环V-1次         */        while (vertexSize > 1) {            while (true) {                /*                 * 从优先队列中寻找有效的边                 */                curEdge = queue.poll();                /*                 * 如果边curEdge的两端顶点不在一个环中,则此curEdge有效                 */                if (union(curEdge.getV(), curEdge.getW())) {                    break;                }            }            /*             * 加入链表中             */            list.add(curEdge);            /*             * 循环次数减一             */            vertexSize--;        }    }    /*     * 将W、V union     */    private boolean union(Vertex V, Vertex W) {        /*         * 顶点V和顶点W不在其他集合中         */        if (map.get(V) == null && map.get(W) == null) {            Set<Vertex> set = new HashSet<Vertex>();            set.add(V);            set.add(W);            /*             * 将顶点V、W关联到同一集合中             */            map.put(V, set);            map.put(W, set);            return true;        } else if (map.get(V) == null) {            /*             * V不属于任何集合中,W属于一个集合,将V加入到W所属集合中去             */            map.get(W).add(V);            map.put(V, map.get(W));            return true;        } else if (map.get(W) == null) {            /*             * W不属于任何集合中,V属于一个集合,将W加入V所属集合中去             */            map.get(V).add(W);            map.put(W, map.get(V));            return true;        }        if (map.get(W) != map.get(V)) {            /*             * V、W分别属于不同集合中 将V所属的集合添加到W所属集合             */            map.get(W).addAll(map.get(V));            for (Vertex vertex : map.get(V)) {                map.put(vertex, map.get(W));            }            return true;        }        return false;    }}

最短权值:16

0 0