【数据结构与算法 | 图篇】最小生成树之Kruskal(克鲁斯卡尔)算法

news2024/12/27 6:15:56

1. 前言

克鲁斯卡尔算法(Kruskal's algorithm)是一种用于寻找加权图的最小生成树(Minimum Spanning Tree, MST)的经典算法。这种算法是由约瑟夫·克鲁斯卡尔(Joseph Kruskal)提出的,并且适用于所有类型的加权无向图,特别是那些边比较稀疏的图

Prim算法更偏重于图的顶点,而克鲁斯卡尔算法更偏重于图的边。

2. 基本步骤

  1. 排序:首先将图中的所有边按照权重(cost)从小到大进行排序。
  2. 初始化:创建一个空集合来保存最小生成树中的边。
  3. 遍历边:依次检查每一条边,检查顺序基于权重的大小。对于每一条边 `(u, v)`:如果加入这条边不会在已选择的边中形成环,则将这条边加入到最小生成树中。如果加入这条边会导致环的形成,则跳过这条边。
  4. 终止条件:重复上述过程,直到最小生成树包含了 `n - 1` 条边(其中 `n` 是顶点的数量),或者没有更多的边可以添加为止。

3. 代码

public class Kruskal {
    // 静态内部类
    static class Edge implements Comparable<Edge>{
        // 顶点集合,构造器赋值,用于toString方法
        List<Vertex> vertices;
        // 下列两属性是定点集合的索引,比如索引0代表顶点v1
        int start;
        int end;
        int weight;

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

        public Edge(List<Vertex> vertices, int start, int end, int weight) {
            this.vertices = vertices;
            this.start = start;
            this.end = end;
            this.weight = weight;
        }

        @Override
        public int compareTo(Edge o) {
            return Integer.compare(this.weight, o.weight);
        }

        @Override
        public String toString() {
            return "v" + vertices.get(start).name + "<=>" + "v"+
                    vertices.get(end).name + "  " + "(" + weight + ")";
        }
    }

    public static void main(String[] args) {
        List<Vertex> vertices = new ArrayList<>();
        Vertex v1 = new Vertex("0");
        Vertex v2 = new Vertex("1");
        Vertex v3 = new Vertex("2");
        Vertex v4 = new Vertex("3");
        Vertex v5 = new Vertex("4");
        Vertex v6 = new Vertex("5");
        Vertex v7 = new Vertex("6");

        vertices.add(v1);
        vertices.add(v2);
        vertices.add(v3);
        vertices.add(v4);
        vertices.add(v5);
        vertices.add(v6);
        vertices.add(v7);

        List<Edge> edges = new ArrayList<>();
        // 由于处理的是加权无向图,所以start:0, end:1与start:1, end:0无区别
        edges.add(new Edge(vertices, 0, 1, 2));
        edges.add(new Edge(vertices, 0, 2, 4));
        edges.add(new Edge(vertices, 0, 3, 1));
        edges.add(new Edge(vertices, 1, 3, 3));
        edges.add(new Edge(vertices, 1, 4, 10));
        edges.add(new Edge(vertices, 2, 3, 2));
        edges.add(new Edge(vertices, 2, 5, 5));
        edges.add(new Edge(vertices, 3, 4, 7));
        edges.add(new Edge(vertices, 3, 5, 8));
        edges.add(new Edge(vertices, 3, 6, 4));
        edges.add(new Edge(vertices, 4, 6, 6));
        edges.add(new Edge(vertices, 5, 6, 1));
        //将边的集合按照从小到大的顺序排列
        PriorityQueue<Edge> queue = new PriorityQueue<>(edges);

        kruskal(vertices.size(), queue);
    }
    public static void kruskal(int size, PriorityQueue<Edge> queue) {
        // 创建一个空集合来保存最小生成树中的边。
        List<Edge> list = new ArrayList<>();
        // 最小生成树的顶点数为size个,所以只需要找到size-1条边即可
        while (list.size() < size - 1){
            // 弹出边权重最小的边判断
            Edge poll = queue.poll();
            // 并查集:用来判断该边加入是否会相交,如果会,则跳过该边
            DisjointSet set = new DisjointSet(size);
            int i = set.find(poll.start);
            int j = set.find(poll.end);
            // 如果不相交
            if(i != j){
                list.add(poll);
                // 将两点相交
                set.union(i, j);
            }
        }
        for (Edge e : list){
            System.out.println(e);
        }
    }
}

输出:

v0<=>v3  (1)
v5<=>v6  (1)
v2<=>v3  (2)
v0<=>v1  (2)
v1<=>v3  (3)
v0<=>v2  (4)

4. 图注

初始时顶点图:

最小生成树的图:

由图:当(v3->v4)(v4->v7) (v7->v6)三顶点已经连通,判断(v3->v6)时,find(2) == find(5),即两个顶点已经连通,(如果加入该边会形成环)所以跳过该边。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2054754.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

七夕情人节动态花瓣表白网页源码

软件介绍 七夕情人节动态花瓣表白网页源码是一款功能强大的表白网页程序&#xff0c;拥有超级好看的花瓣表白效果和多种不同的动态切换效果&#xff0c;非常适合七夕表白活动。 拥有独特的设计风格和花瓣表白效果&#xff0c;可以让用户在表白过程中更加浪漫和温馨。该程序还…

Seaborn:基于 Matplotlib 的高级绘图库,提供了更高级的接口来绘制吸引人的统计图形。

引言 Seaborn 是基于 Matplotlib 的高级数据可视化库&#xff0c;专为绘制统计图形而设计。相比于 Matplotlib&#xff0c;Seaborn 提供了更高级的接口&#xff0c;简化了绘图过程&#xff0c;同时默认的美观配色和样式使得图形更加吸引人。Seaborn 特别适合用于探索性数据分析…

Cesium 实战 - 自定义纹理材质系列之 - 半球雷达效果(力场闪烁)

Cesium 实战 - 自定义纹理材质系列之 - 半球雷达效果(力场闪烁) 核心代码完整代码在线示例Cesium 给实体对象(Entity)提供了很多实用的样式,基本满足普通项目需求; 但是作为 WebGL 引擎,肯定不够丰富,尤其是动态效果样式。 对于实体对象(Entity),可以通过自定义材…

springsecurity 登录认证一(ajax)

一、准备工作 1.1 导入依赖 因springboot 3.0 以上版本只能支持java17 顾使用2.5.0 版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.0</version><…

CSDN AI-WEB-1.0 攻略

找到一个目标靶场的IP &#xff0c; 这里以172.16.1.98 为例 1、使用命令 /robots.txt 来确定目录 2、分别测试两个文件 均无法访问&#xff0c;可返回其根目录查询 3、到根目录&#xff0c;出现搜索框 4、输入ID为1 5、使用虚拟机kali的终端 搜索命令 dirsearch -u http:…

Python青少年简明教程:基础知识

Python青少年简明教程&#xff1a;基础知识 Python是大小写敏感的语言。编程语言中的“大小写敏感”意味着该语言在识别标识符、关键字或者其他语法元素时&#xff0c;会区分字母的大小写。在这种语言中&#xff0c;大写字母和小写字母被视为不同的字符&#xff0c;因此&#x…

[论文翻译]使用 BERT 检测安卓恶意软件

Android Malware Detection Using BERT Souani B, Khanfir A, Bartel A, et al. Android malware detection using bert[C]//International Conference on Applied Cryptography and Network Security. Cham: Springer International Publishing, 2022: 575-591. 摘要 在本文…

cad文件被写保护怎么解除保护?

CAD文件被写保护怎么解除保护?四五设计网小编给大家整理出的方法希望能够帮助到大家&#xff01; 解除CAD文件写保护的最简单方法是创建一个文件的副本&#xff0c;并在副本上进行编辑。 原文件可能因为文件属性或权限设置而被设置为写保护。创建副本不会改变原始文件的保护…

指针详解(六)

目录 1. sizeof 和 strlen 1&#xff09;sizeof 2&#xff09;strlen 3&#xff09;sizeof 和 strlen的区别 2. 数组和指针试题解析 1&#xff09;一维数组 2&#xff09;字符数组 3&#xff09;二维数组 3. 指针运算试题解析 1. sizeof 和 strlen 1&#xff09;sizeo…

【hot100篇-python刷题记录】【全排列】

R5-回溯篇 思路也是如下&#xff1a; 层层固定 class Solution:def permute(self, nums: List[int]) -> List[List[int]]:#x代表当前固定/选择的数的下标def dfs(x):if xlen(nums)-1:ret.append(list(nums))returnfor i in range(x,len(nums)):#交换&#xff0c;将nums[i]固…

SAP_MM模块-MASS批量操作技巧

业务背景: 现在想要获得平台的流量券,每天必须要发两篇文章才行,但是一天发两篇的话,按照我的写作风格,很难写得出来~~我又不想把原本一篇完整的文章给拆分开来,那怎么办呢??今天就讲一下我常用的批量操作事务码MASS吧。 一、功能概述; MASS是系统标准的批量操作程序,…

HCIP第十一(生成树基础知识点)

企业网三层架构-冗余&#xff08;线路&#xff0c;设备&#xff0c;网关&#xff0c;电源Ups&#xff09; 三层架构-冗余&#xff0c;线路冗余&#xff1a;二层桥接技术 一台交换机上的一个接口可以映射多个MAC地址&#xff0c;但是一个MAC地址只能对应一个接口 当交换机触环…

2024.8.19 学习记录 —— 作业

一、TCP机械臂测试 #include <myhead.h>#define SER_PORT 8888 // 与服务器保持一致 #define SER_IP "192.168.0.114" // 服务器ip地址int main(int argc, const char *argv[]) {// 创建文件描述符打开键盘文件int fd open("/dev/input/event1…

设备实时数据采集:开启制造业智能化、自动化的新篇章

传统制造业在进行生产过程中&#xff0c;会涉及到设备实时数据采集需求&#xff0c;这些数据对于监控生产流程、优化生产效率、保证产品质量以及降低成本等方面至关重要。以下是一些常见的数据采集需求&#xff1a; 1.生产数据&#xff1a;包括生产数量、生产批次、生产速度等&…

Facebook与区块链:社交网络如何融入去中心化技术

随着区块链技术的飞速发展&#xff0c;去中心化理念逐渐渗透到各个领域&#xff0c;社交网络也不例外。作为全球领先的社交平台&#xff0c;Facebook在这一趋势下开始积极探索区块链技术的潜力&#xff0c;希望利用这一前沿技术来提升平台的安全性、透明度和用户控制权。本文将…

Maven-02.介绍安装

一.介绍 首先从本地仓库中寻找所需要的jar包&#xff0c;如果没有就从中央仓库中寻找。然后从中央仓库中下载使用。但是中央仓库的服务器在国外&#xff0c;因此速度和稳定性都不好&#xff0c;因此我们在中间设立远程仓库&#xff08;私服&#xff09;&#xff0c;远程仓库一般…

光伏气象站——提升光伏发电效率和稳定运行

光伏气象站作为现代光伏电站的必备组成部分&#xff0c;‌特别适用于地理分布广泛、‌气象条件复杂多变的地区&#xff0c;‌如山区、‌森林或分散的屋顶安装等。‌这些地方由于可能存在微气候差异&#xff0c;‌对光伏系统的运行效率和性能有着显著影响。‌因此&#xff0c;‌…

LeetCode:3148. 矩阵中的最大得分(DP Java)

目录 3148. 矩阵中的最大得分 题目描述&#xff1a; 实现代码与解析&#xff1a; DP 原理思路&#xff1a; 3148. 矩阵中的最大得分 题目描述&#xff1a; 给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧…

STM32裸机和RTOS中的线程安全问题及STM32cubeMX中的线程安全策略

STM32线程安全问题 术语“线程” 和“多线程” 适用于裸机和基于RTOS的应用程序&#xff0c;线程安全问题并不只存在于基于RTOS的应用程序中&#xff1b;裸机应用程序中也存在这个问题&#xff0c;在裸机应用程序中&#xff0c;中断服务程序允许调用C库函数。线程安全问题可能…

『Z-Workshop』 The Graph workshop mini hackathon活动

Community Meetup In Hangzhou ZJUBCA 2024 求是 创新 概述 / OVERVIEW The Graph作为一个去中心化的查询协议&#xff0c;为区块链数据的索引和查询提供了强大的支持。我们希望通过这场黑客松&#xff0c;激发大家对区块链技术更深层次的探索和应用&#xff0c;共同推动这一…