Java版-图论-最小生成树-Kruskal算法

实现描述

为了造出一棵最小生成树,我们从最小边权的边开始,按边权从小到大依次加入,如果某次加边产生了环,就扔掉这条边,直到加入了 n-1 条边,即形成了一棵树。

实现代码

  1. 首选我们对所有的边,按照权重排序;
  2. 之后,从小到大选择边,如果当前的边已经连通过了,则放弃此边,查看下一条边;若没有连通过,通过并查集进行连通;
  3. 直至所有点都访问过,此时,完成。

如上图,节点0~5,边关系如上;

先对边权重进行从小到大排序,得到:

java 复制代码
[{
	"u":4,
	"v":5,
	"weight":1
},{
	"u":0,
	"v":5,
	"weight":3
},{
	"u":1,
	"v":2,
	"weight":4
},{
	"u":0,
	"v":1,
	"weight":5
},{
	"u":2,
	"v":3,
	"weight":5
},{
	"u":3,
	"v":4,
	"weight":5
},{
	"u":3,
	"v":5,
	"weight":6
},{
	"u":0,
	"v":3,
	"weight":7
},{
	"u":0,
	"v":2,
	"weight":8
},{
	"u":2,
	"v":5,
	"weight":9
}]

然后依次选择排序后的边:

下面代码对应上图数据及其过程:

java 复制代码
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;

import java.util.*;

public class kruskal {

    /**
     * 边定义
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class Edge implements Comparable<Edge> {
        int u, v;
        int weight;

        @Override
        public int compareTo(@NotNull Edge o) {
            return weight - o.weight;
        }
    }


    static List<Edge> getKruskalEdges(int nodeNum, int[][] grid) {
        List<Edge> result = new LinkedList<>();
        List<Edge> edges = new LinkedList<>();
        for (int i = 0; i < grid.length; i++) {
            int u = grid[i][0];
            int v = grid[i][1];
            int weight = grid[i][2];
            edges.add(new Edge(u, v, weight));
        }
        Collections.sort(edges);
        UnionFindTemplate uf = new UnionFindTemplate(nodeNum);
        Set<Integer> visited = new HashSet<>();
        for (Edge edge : edges) {
            if (uf.connected(edge.u, edge.v)) {
                continue;
            }
            uf.union(edge.u, edge.v);
            visited.add(edge.u);
            visited.add(edge.v);
            result.add(edge);
            if (visited.size() == nodeNum) {
                break;
            }
        }
        return result;
    }



    public static void main(String[] args) {
        int nodeNum = 6;
        int[][] grid = {
                {0, 1, 5},
                {0, 5, 3},
                {0, 3, 7},
                {0, 2, 8},
                {1, 2, 4},
                {2, 5, 9},
                {3, 5, 6},
                {2, 3, 5},
                {3, 4, 5},
                {4, 5, 1}
        };
        System.out.println(JSONObject.toJSONString(getKruskalEdges(nodeNum, grid)));
    }
}

其中,并查集模版的实现如下:

java 复制代码
public class UnionFindTemplate {
    int[] parent;
    int[] size;
    int n;
    public int setCount;//连通分量个数

    public UnionFindTemplate(int n) {
        this.n = n;
        this.parent = new int[n];
        this.size = new int[n];
        setCount = n;
        Arrays.fill(this.size, 1);
        for (int i = 0; i < n; ++i) {
            parent[i] = i;
        }
    }

    public int findParent(int x) {
        if (parent[x] == x) {
            return x;
        } else {
            parent[x] = findParent(parent[x]);
            return parent[x];
        }
    }

    public void union(int x, int y) {
        x = findParent(x);
        y = findParent(y);
        if (x == y) {
            return;
        }
        if (size[x] < size[y]) {
            int temp = x;
            x = y;
            y = temp;
        }
        //y合并到x
        parent[y] = x;
        size[x] += size[y];
        setCount--;
    }

    public boolean connected(int x, int y) {
        x = findParent(x);
        y = findParent(y);
        return x == y;
    }

}
相关推荐
摇滚侠5 分钟前
Vue 项目实战《尚医通》,完成确定挂号业务,笔记46
java·开发语言·javascript·vue.js·笔记
正在走向自律13 分钟前
豆包编程模型Doubao-Seed-Code深度体验,从零开始构建全栈项目的完整指南
java·服务器·数据库·doubao·claude code·火山方舟
钱多多_qdd16 分钟前
基础篇:IoC(九):应用上下文ApplicationContext
java·spring
q***558930 分钟前
SpringSecurity 实现token 认证
java
Greedy Alg30 分钟前
LeetCode 72. 编辑距离(中等)
算法
合作小小程序员小小店30 分钟前
web网页开发,在线%医院诊断管理%系统,基于Idea,html,css,jQuery,java,jsp,ssh,mysql。
java·前端·css·数据库·jdk·html·intellij-idea
xinxingrs31 分钟前
贪心算法、动态规划以及相关应用(python)
笔记·python·学习·算法·贪心算法·动态规划
秋邱44 分钟前
驾驭数据洪流:Python如何赋能您的数据思维与决策飞跃
jvm·算法·云原生·oracle·eureka·数据分析·推荐算法
程序猿_极客1 小时前
【2025最新】 Java入门到实战:包装类、字符串转换、equals/toString + 可变字符串,一篇搞定开发高频场景(含案例解析)
java·开发语言·java进阶·面试核心·java快速入门
侯小啾1 小时前
【23】C语言 左移(<<) 与 右移(>>) 位运算符在处理像素中的应用
c语言·算法·位运算·右移·左移