前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图论-最小生成树kruskal算法(Java)

图论-最小生成树kruskal算法(Java)

作者头像
aruba
发布2021-12-06 17:11:32
7800
发布2021-12-06 17:11:32
举报
文章被收录于专栏:android技术

和prim算法以顶点为出发点不同,kruskal算法以边为中心,将所有边以小到大排序,遍历边,如果当前边的两个顶点有一个没有访问过,则记录该边,直到记录的边到达顶点数-1时,即所有顶点都可以相连,为最小生成树 实现代码:

代码语言:javascript
复制
    public static class Kruskal {
        private int verticeSize;// 顶点数量
        private int[] vertices; // 顶点数组
        private int[][] matrix; // 矩阵
        private int edgeSize;
        private static final int MAX = Integer.MAX_VALUE;
        private Edge[] edges;

        public Kruskal(int verticeSize) {
            this.verticeSize = verticeSize;
            matrix = new int[verticeSize][verticeSize];
        }

        public void kruskal() {
            //存放排序边
            PriorityQueue<Edge> edgePriorityQueue = new PriorityQueue<>(new Comparator<Edge>() {
                @Override
                public int compare(Edge o1, Edge o2) {
                    return o1.weight - o2.weight;
                }
            });
            //遍历边
            for (int i = 0; i < verticeSize; i++) {
                for (int j = 0; j < verticeSize; j++) {
                    if (matrix[i][j] != 0 && matrix[i][j] != MAX) {
                        //加入队列
                        edgePriorityQueue.offer(new Edge(i, j, matrix[i][j]));
                    }
                }
            }

            //辅助数组 索引表示边的一段顶点,值为边的另一端顶点
            int[] edgeIndex = new int[verticeSize];
            //存放最小边
            Edge[] edges = new Edge[verticeSize - 1];
            int index = 0;
            while (!edgePriorityQueue.isEmpty()) {
                Edge edge = edgePriorityQueue.poll();
                //获取与顶点start相连的最远顶点
                int start = getEnd(edgeIndex, edge.start);
                //获取与顶点end相连的最远顶点
                int end = getEnd(edgeIndex, edge.end);

                if (start != end) {
                    if (start < end) {//我们用的是最远顶点,该判断保证有小到大指向的
                        edgeIndex[start] = end;
                    } else {
                        edgeIndex[end] = start;
                    }
                    edges[index++] = edge;
                } else {//最远顶点相同表示start和end已经相连了

                }

                if (index == verticeSize - 1) break;//都找到了
            }

            //输出
            int lengh = 0;
            for (int i = 0; i < index; i++) {
                lengh += edges[i].weight;
            }
            System.out.println("最小生成树的权值:" + lengh);
            char[] chars = new char[verticeSize];
            chars[0] = 'A';
            chars[1] = 'B';
            chars[2] = 'C';
            chars[3] = 'D';
            chars[4] = 'E';
            chars[5] = 'F';
            chars[6] = 'G';

            for (int i = 0; i < index; i++) {
                System.out.printf("(%s, %s)---> %d \n", chars[edges[i].start], chars[edges[i].end], matrix[edges[i].start][edges[i].end]);
            }
        }

        /**
         * 获取与顶点v相连的最远顶点
         *
         * @param edgeIndex
         * @param v
         * @return
         */
        private int getEnd(int[] edgeIndex, int v) {
            int ret = v;
            while (edgeIndex[ret] != 0) {
                ret = edgeIndex[ret];
            }
            return ret;
        }

        public static class Edge {
            int start;
            int end;
            int weight;

            public Edge(int start, int end, int weight) {
                this.start = start;
                this.end = end;
                this.weight = weight;
            }
        }
    }

测试代码:

代码语言:javascript
复制
        Kruskal graph = new Kruskal(7);
        int[] v0 = new int[] {0, 50, 60, Kruskal.MAX, Kruskal.MAX,Kruskal.MAX,Kruskal.MAX};
        int[] v1 = new int[] {50, 0, Kruskal.MAX, 65, 40,Kruskal.MAX,Kruskal.MAX};
        int[] v2 = new int[] {60, Kruskal.MAX, 0, 52, Kruskal.MAX,Kruskal.MAX,45};
        int[] v3 = new int[] {Kruskal.MAX, 65, 52, 0, 50,30,42};
        int[] v4 = new int[] {Kruskal.MAX, 40, Kruskal.MAX, 50, 0,70,Kruskal.MAX};
        int[] v5 = new int[] {Kruskal.MAX, Kruskal.MAX, Kruskal.MAX, 30,70,0,Kruskal.MAX};
        int[] v6 = new int[] {Kruskal.MAX, Kruskal.MAX, 45, 42,Kruskal.MAX,Kruskal.MAX,0};

        graph.matrix[0] = v0;
        graph.matrix[1] = v1;
        graph.matrix[2] = v2;
        graph.matrix[3] = v3;
        graph.matrix[4] = v4;
        graph.matrix[5] = v5;
        graph.matrix[6] = v6;

        graph.kruskal();

结果: 最小生成树的权值:257 (D, F)---> 30 (B, E)---> 40 (G, D)---> 42 (C, G)---> 45 (A, B)---> 50 (D, E)---> 50

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/8/17 上,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档