Kruskal算法求最小生成树(加边法)

一、算法逻辑

想要轻松形象理解Kruskal算法的算法逻辑,视频肯定比图文好。

小编看过很多求相关的教学视频,这里选出一个我认为最好理解的这一款安利给大家。

因为他不仅讲解细致,而且还配合了动画演示,可以说把一个抽象的东西讲的非常的形象了。

B站链接:【最小生成树(Kruskal(克鲁斯卡尔)和Prim(普里姆))算法动画演示】

二、JAVA实现

1、实现这个算法,要建立一个图,才可以,这里小编直接给一个,

基于邻接矩阵的图:

public class GraphByMatrix {

    private char[] arrayV;//顶点数组

    private int[][] matrix;//矩阵,存放每一个边的权重

    private boolean isDirect;//是否是有向图

    /**
     * 构造方法
     *
     * @param size     代表当前顶点的个数
     * @param isDirect  是否是有向图,true是有向图
     */

    public GraphByMatrix(int size, boolean isDirect) {
        this.arrayV = new char[size];//顶点的个数是size
        matrix = new int[size][size];
        for (int i = 0; i < size; i++) {
            Arrays.fill(matrix[i], Constant.MAX);
        }
        this.isDirect = isDirect;
    }



    /**
     * @param srcV   起点
     * @param destV  终点
     * @param weight 权值
     */
    public void addEdge(char srcV, char destV, int weight) {//重载之一,用来建立普通图
        int srcIndex = getIndexOfV(srcV);
        int destIndex = getIndexOfV(destV);
        matrix[srcIndex][destIndex] = weight;
        //如果是无向图 那么相反的位置 也同样需要置为空
        if (!isDirect) {
            matrix[destIndex][srcIndex] = weight;
        }
    }

    /**
     * @param srcIndex 起点
     * @param desIndex 终点
     * @param weight   权重
     */
    public void addEdge(int srcIndex, int desIndex, int weight) {//重载两个之一,用来建立最小生成树

        matrix[srcIndex][desIndex] = weight;
        //如果是无向图 那么相反的位置 也同样需要置为空
        if (!isDirect) {
            matrix[desIndex][srcIndex] = weight;
        }
    }


    /**
     * 获取顶点V的下标
     *
     * @param v
     * @return
     */
    private int getIndexOfV(char v) {
        for (int i = 0; i < arrayV.length; i++) {
            if (arrayV[i] == v) {
                return i;
            }
        }
        return -1;
    }

  
    public void printGraph() {
        for (int i = 0; i < arrayV.length; i++) {
            System.out.print(arrayV[i] + " ");
        }
        System.out.println();
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if (matrix[i][j] == Constant.MAX) {
                    System.out.print("∞ ");
                } else {
                    System.out.print(matrix[i][j] + " ");
                }
            }
            System.out.println();
        }
    }




    /**
     * 定义了一个边的抽象类
     * 用来存储边的
     */
    static class Edge {
        public int srcIndex;
        public int destIndex;
        public int weight;//权重

        public Edge(int srcIndex, int destIndex, int weight) {
            this.srcIndex = srcIndex;
            this.destIndex = destIndex;
            this.weight = weight;
        }
    }
    
    public static void main(String[] args) {


    }
}

接下来对克鲁苏卡尔算法进行实现:

因为树一定是无向图,而无向图,用邻接矩阵表示,有一个特点,等一下会用到,以下边这个无向图为例:

圆圈代表不存在边,1代表有边

我们发现这个矩阵代码

    /**
     * 克鲁苏卡尔算法
     * 求最小生成树(无向图)
     * 返回总权重
     * minTree同时也被建立
     *
     * @param minTree
     */
    public int kruskal(GraphByMatrix minTree) {

        /**
         * 第一步:对所有的边进行排序(从小到大)
         */
        PriorityQueue<Edge> minHeap = new PriorityQueue<>();//建立一个小根堆来实现排序
        int n=arrayV.length;
        for (int i = 0; i < n; i++) {


            for (int j = 0; j < n; j++) {

                /*
                 * i<j的原因:
                 * //因为是无向图,所以根据对称性,只用录入一个方向的边的权值即可
                 * */
                if (j < i && matrix[i][j] != Constant.MAX) {//邻接矩阵的元素如果是Constant.Max说明边不存在
                    minHeap.offer(new Edge(i, j, matrix[i][j]));//i到j,权值是matrix[i][j]
                }
            }
        }

        //程序到达此处,已经排序好所有的边了

        //初始化查集后,每一个元素都是独立的集合
        UnionFindSet unionFindSet=new UnionFindSet(n);//定义一个并查集,大小就是图顶点数

        int size=0;//记录已经寻找到的边的个数,只要等于n-1,最小生成树就找到了
int totalWeight=0;//用来记录最小总权值
        while(size<n-1&&!minHeap.isEmpty()){//如果不加!minHeap.isEmpty()这个条件,此图若没有最小生成树(所给的图不是连通图),那么程序会死循环
            Edge edge=minHeap.poll();//出一个边
            int src=edge.srcIndex;//起点下标
            int des=edge.destIndex;//终点下标
            if(!unionFindSet.isSameUnionFindSet(src,des)){//不是同一个集合,进来(如果是同一个集合,就代表形成了环!)
                minTree.addEdge(edge.srcIndex,edge.srcIndex,edge.weight);//给最小生成树增加一条边
                size++;//尺寸加加
                unionFindSet.union(src,des);//合并两个顶点构成的边
                totalWeight+=edge.weight;
            }
        }

        if(size==n-1){
            return totalWeight;
        }else{//size!=n-1说明所给的图,不是连通图,找不到最小生成树
            return -1;//返回一个无效值
        }

    }

是关于对角线对称的,这个要记住等一下会用到。

代码加注释:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32高级控制定时器(STM32F103):输入捕获模式

目录 概述 1 输入捕获模式 1.1 原理介绍 1.2 实现步骤 1.3 发生输入捕获流程 2 使用STM32Cube配置工程 2.1 软件环境 2.2 配置参数 2.3 生成项目文件 3 功能实现 3.1 PWM调制占空比函数 3.2 应用函数库 4 测试 4.1 功能框图 4.2 运行结果 源代码下载地址&#xf…

微软联手清华,AI注释让文本到图像生成更符合人类偏好

获取本文论文原文PDF&#xff0c;请在公众号【AI论文解读】留言&#xff1a;论文解读 摘要 本研究展示了利用人类偏好数据集来精细调整文本到图像生成模型的潜力&#xff0c;增强了生成图像与文本提示之间的一致性。尽管取得了进展&#xff0c;现有的人类偏好数据集要么构建成…

【网络协议】划重点啦!TCP与UDP的重点面试题!!!

1. 为什么建立TCP连接是三次握手&#xff0c;而关闭连接却是四次挥手呢&#xff1f; 这是因为服务端的 LISTEN 状态下的 SOCKET 当收到 SYN 报文的建连请求后&#xff0c;它可以把 ACK和 SYN&#xff08;ACK 起应答作用&#xff0c; 而 SYN 起同步作用&#xff09; 放在一个报文…

飞控如何连接地面站

飞控连接地面站有两种方法&#xff0c;一种是USB线&#xff0c;一种是数传。 一.USB线连接 usb连接线使用安卓手机线&#xff08;一般人都有吧&#xff0c;没有很容易买和借到&#xff09; 电脑打开地面站软件。 端口选择C OM口&#xff0c;不要选择auto&#xff0c;如果你…

详细分析 tar: xx:无法 open: 没有那个文件或目录 的解决方法

目录 1. 问题所示2. 原理分析3. 解决方法 1. 问题所示 对于此问题处理起来比较简易&#xff0c;对此放置在运维的专栏模块 在执行解压的时候出现如下问题&#xff1a; (pgm37) l228l228:~/huoyanhao/pytorch-glow-master/pytorch-glow-master$ tar -xvf celeb-tfr.tar tar: …

计算机网络路由协议之内部网关协议RIP例题与详解

互联网的路由选择协议 路由器转发表的路由协议如何得出呢&#xff1f; 使用路由算法进行&#xff0c;路由算法可以分为两类&#xff1a; 静态路由选择策略和动态路由选择策略。 静态路由选择策略&#xff1a; 非自适应路由选择&#xff0c;人工配置每一条路由。 动态路由选…

遗留和现代数据库中的向量搜索

遗留和现代数据库中的向量搜索 image1 向量数据库是一种将数据&#xff08;包括文本、图像、音频和视频&#xff09;存储为向量的数据库&#xff0c;向量是高维空间中对象或概念的数学表示。 注意&#xff1a;根据数据的复杂程度和细节&#xff0c;每个向量的维数可能差别很大&…

DOS学习-目录与文件应用操作经典案例-attrib

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 DOS系统中的attrib命令是一个用于显示或更改文件&#…

【CCF CAT- 全国算法精英大赛(第二场)】训练一

目录 前言训练一A题 Mysterious Rune StringB题 TouristC题 The diameter of a rectangleD题 Card 前言 我飘了&#xff0c;全国算法精英大赛本来就是三人赛&#xff0c;但是我认为自己能一个人当三个人用&#xff0c;结果被训练赛拷打。 另外赛氪这个平台有一个严重的问题&…

Diffusion相关原理

Diffusion相关原理 1、数学&#xff1a;重参数化 &#xff08;用于高斯拟合求导&#xff09;变分推断原理 &#xff08;用于损失&#xff09; 2、生成模型系列1、AE自动编码器&#xff08;AutoEncoder&#xff09;2.VAE的模型架构模型原理数学原理AE和VAE对比 3、DDMP图像高斯加…

2024 年你应该选择哪个开源大模型?

自2017年发表的论文《Attention Is All You Need》发明了Transformer架构以来&#xff0c;自然语言处理&#xff08;NLP&#xff09;取得了巨大的进展。随着2022年11月ChatGPT的发布&#xff0c;大型语言模型&#xff08;LLM&#xff09;引起了广泛关注。 你是否想在自己的用例…

揭秘网络编程:同步与异步IO模型的实战演练

摘要 ​ 在网络编程领域&#xff0c;同步(Synchronous)、异步(Asynchronous)、阻塞(Blocking)与非阻塞(Non-blocking)IO模型是核心概念。尽管这些概念在多篇文章中被广泛讨论&#xff0c;它们的抽象性使得彻底理解并非易事。本文旨在通过具体的实验案例&#xff0c;将这些抽象…

HTML+CSS+JavaScript网页制作案例教程第2版-黑马程序员-第9章动手实践

文章目录 效果代码网盘 效果 代码 index.html <!doctype html> <html> <head> <meta charset"utf-8"> <title>通栏效果</title> <link rel"stylesheet" type"text/css" href"index.css"> …

【源码】2024完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城

后台可以自由拖曳修改前端UI页面 还支持虚拟商品自动发货等功能 前端UNIAPP 后端PHP 一键部署版本 获取方式&#xff1a; 微&#xff1a;uucodes

基于Java+SpringBoot+Mybaties-plus+Vue+elememt + uniapp 驾校预约平台 的设计与实现

一.项目介绍 系统角色&#xff1a;管理员、教练、学员 小程序(仅限于学员注册、登录)&#xff1a; 查看管理员发布的公告信息 查看管理员发布的驾校信息 查看所有教练信息、预约(需教练审核)、评论、收藏喜欢的教练 查看管理员发布的考试信息、预约考试(需管理…

设计模式:原型模式(Prototype)

设计模式&#xff1a;原型模式&#xff08;Prototype&#xff09; 设计模式&#xff1a;原型模式&#xff08;Prototype&#xff09;模式动机模式定义模式结构时序图模式实现在单线程环境下的测试在多线程环境下的测试模式分析优缺点适用场景应用场景模式扩展应用实例实例 1&am…

【软件设计师】——6.程序设计语言与语言处理程序

目录 6.1基本概念 6.2编译与解释 6.3文法 6.4有限自动机 6.5正规式 6.6 表达式 6.7 传值与引用 6.8 数据类型与程序控制结构 6.9 程序语言特点 6.10 Java程序设计 6.11 C 6.12 python 6.1基本概念 语句&#xff1a;高级程序设计语言中描述程序的运算步骤、控制结构、…

hubilder Android模拟器华为手机连接不上

APP真机测试注意点&#xff1a; 1. 同一个局域网下 2. 手机连接USB模式&#xff08;华为选择USB配置&#xff1a;音频来源&#xff09; &#xff0c;开发者模式 3. 实在不行重启HBuilderX再运行真机 可是卡在了“正在安装手机端HBuilder调试基座...” 就没反应了&#xff1f;&…

【荐闻】空中目标检测综述

https://t.zsxq.com/tgUjbhttps://t.zsxq.com/tgUjb 这篇综述论文全面回顾了空中目标检测的最新进展&#xff0c;包括五个不平衡问题、相关方法、实际应用和性能评估。以下是对论文内容的详细描述&#xff1a; 1&#xff09;引言&#xff1a;介绍了空中目标检测的概念&#x…

【搭建大语言模型】使用LocalGPT搭建本地大语言模型服务并实现远程访问进行交互

文章目录 前言环境准备1. localGPT部署2. 启动和使用3. 安装cpolar 内网穿透4. 创建公网地址5. 公网地址访问6. 固定公网地址 前言 本文主要介绍如何本地部署LocalGPT并实现远程访问&#xff0c;由于localGPT只能通过本地局域网IP地址端口号的形式访问&#xff0c;实现远程访问…