Kruskal算法用于生成图的最小生成树MST,不多说下面直接进入主题!

一、实现Kruskal算法需要会的数据结构知识

1、最小堆:包括最小堆的初始化、插入和删除操作
最小堆的作用:每次从边的集合中选出权重最小的边,将其加入到MST中(当然此边当和MST中的元素构成环时不满足)

2、等价类(并查集)
并查集的作用:便是判断加入到MST中的边是否会构成环

3、EdgeNode类
在Kruskal算法中,图是加权图,为了更好地对边进行操作,我们需要定义一个EdgeNode类来对图中的加权边进行操作

只有弄明白上面的数据结构知识,下面才能够比较看得明白!


二、Kruskal算法实现的具体思路

首先给出伪代码:

其实Kruskal算法的思想很简单,是典型的贪婪算法

1、首先我们利用并查集的思想将图中的所有顶点初始化成一棵树,每个顶点对象包含两个域:parent域和root域

2、按照每条边权重的大小对所有未加入MST中的边进行排序,利用最小堆!算法复杂度小!

3、每次选出权重最小的边加入到MST中,利用并查集的思想,判断两个顶点是否在一个树中,也就是是否会构成环!

4、当所有的边操作完后便形成了我们需要的最小生成树MST


三、Kruskal算法java具体实现源码

1、EdgeNode类

public class EdgeNode {int weight;int u,v;
}

2、Kruskal算法实现类

import java.util.ArrayList;
import java.util.Scanner;
/*** <pre>* 使用kruskal算法生成图的MST* 其中:* 1>.图的顶点存在了数组中,存在是int* 2>.图的带权边使用了EdgeNode对象,存在了数组中* 3>.边按照权重进行排序利用最小堆进行排序,每次取出最小堆的根节点,便是权最小的边* 4>.每次向MST中添加边肯定添加最小权的边,唯一条件便是不构成环* 5>.上述不构成环是利用等价类<并查集>实现的* 6>.并查集实现:树!每个顶点两个域:parent域&root域!find-union!重量规则!</pre>* @author King**/
public class Kruskal {boolean[] root;int[] parent;int currentSize=0;int maxSize=0;EdgeNode[] minHeap=new EdgeNode[20];/*** 初始化每个顶点为一个类* @param verNum 顶点的数量*/public void initialize(int verNum){root=new boolean[verNum+1];parent=new int[verNum+1];for(int vertex=1;vertex<=verNum;vertex++){parent[vertex]=1;root[vertex]=true;}}/*** 寻找某个顶点元素所在的类* @param vertex 顶点* @return 返回的是顶点所在的类*/public int find(int vertex){while(!root[vertex]){vertex=parent[vertex];}return vertex;}/*** 利用重量规则将两个根节点为i,j的类合并* @param i 根节点为i* @param j 根节点为j*/public void union(int i,int j){if(parent[i]<parent[j]){parent[j]+=parent[i];root[i]=false;parent[i]=j;}else{parent[i]+=parent[j];root[j]=false;parent[j]=i;}}/*** 通过weight构建以EdgeNode为节点的最小堆* @param edgeNode为带权的边集*/public void createMinHeap(EdgeNode[] edgeNode){currentSize=edgeNode.length;maxSize=minHeap.length;if(currentSize>=maxSize){maxSize*=2;minHeap=new EdgeNode[maxSize];}for(int i=0;i<currentSize;i++)minHeap[i+1]=edgeNode[i];int y,c;for(int i=currentSize/2;i>=1;i--){EdgeNode node=minHeap[i];y=node.weight;c=2*i;while(c<currentSize){if(c<=currentSize && minHeap[c].weight>minHeap[c+1].weight)c++;if(minHeap[c].weight>=y)break;minHeap[c/2]=minHeap[c];c=c*2;}minHeap[c/2]=node;}}/*** 最小堆删除两种思路,一种和前面一样,就是一直跟踪放在根节点的那个最后一个节点最终插入的位置* 另一种思路便是每一次完成完整的交换然后下一一层在进行同样处理*/public EdgeNode deleteMinHeap(){if(currentSize<1)System.out.println("堆已经为空!无法执行删除");EdgeNode node=minHeap[1];minHeap[1]=minHeap[currentSize];currentSize-=1;int c=2,j=1;EdgeNode node1=minHeap[currentSize+1];while(c<=currentSize){if(c<currentSize && minHeap[c].weight>minHeap[c+1].weight)c++;if(node1.weight<=minHeap[c].weight)break;minHeap[j]=minHeap[c];j=c;c=c*2;}minHeap[j]=node1;return node;}/*** 根据图的顶点集合带权边集生成MST* @param verArray 顶点集* @param edgeNode 带权边集*/public void minSpanningTree(int[] verArray,EdgeNode[] edgeNode){ArrayList<EdgeNode> nodeList=new ArrayList<EdgeNode>();initialize(verArray.length);createMinHeap(edgeNode);for(int i=1;i<=currentSize;i++){System.out.println(minHeap[i].u+" "+minHeap[i].v+" "+minHeap[i].weight);}for(int i=0;i<edgeNode.length;i++){EdgeNode node=deleteMinHeap();int jRoot=find(node.u);int kRoot=find(node.v);if(jRoot!=kRoot){nodeList.add(node);union(jRoot,kRoot);}}System.out.println("使用Kruskal算法得到图的最小生成树为:");for(int i=0;i<nodeList.size();i++){System.out.println(nodeList.get(i).u+" "+nodeList.get(i).v+" "+nodeList.get(i).weight);}}public static void main(String[] args) {System.out.println("请输出图的顶点数和边数:");@SuppressWarnings("resource")Scanner scan=new Scanner(System.in);int verNum=scan.nextInt();int edgeNum=scan.nextInt();int[] verArray=new int[verNum];System.out.println("请依次输入顶点:");for(int i=0;i<verNum;i++){int vertex=scan.nextInt();verArray[i]=vertex;}EdgeNode[] edgeNode=new EdgeNode[edgeNum];System.out.println("请依次输入边的顶点和权重:");for(int i=0;i<edgeNum;i++){int u=scan.nextInt();int v=scan.nextInt();int weight=scan.nextInt();EdgeNode node=new EdgeNode();node.u=u;node.v=v;node.weight=weight;edgeNode[i]=node;}Kruskal kruskal=new Kruskal();kruskal.minSpanningTree(verArray,edgeNode);}
}

测试所用的加权无向图如下所示:

测试输入数据格式截图(部分):

测试结果为:

Kruskal算法实现最小生成树MST(java)相关推荐

  1. ds图—最小生成树_Java: Kruskal算法生成最小生成树(邻接矩阵)

    Java: Kruskal算法生成最小生成树(邻接矩阵): package 输出: Kruskal=36: (E,F) (C,D) (D,E) (B,F) (E,G) (A,B) 分析: Java: ...

  2. CSP认证201412-4 最优灌溉[C++题解]:最小生成树裸题、Kruskal算法求最小生成树

    题目分析 来源:acwing 分析:这是一道最小生成树的裸题. 这里默写Kruskal求最小生成树的最小费用的模板. 最小生成树模板请参考笔者的另一篇博文: 最小生成树板子-AcWing 859. K ...

  3. C语言实现克鲁斯卡尔Kruskal算法求最小生成树(附完整源码)

    Kruskal算法求最小生成树 Edge结构体,Graph结构体 Kruskal算法求最小生成树完整源码(定义,实现,main函数测试) Edge结构体,Graph结构体 // a structure ...

  4. 作业1-采用Prim算法和Kruskal算法构造最小生成树

    采用Prim算法和Kruskal算法构造最小生成树 实验报告 1.问题 2.解析 (1)Prim算法 (2)Kruskal算法 3.设计 (1)Prim算法 (2)Kruskal算法 4.分析 (1) ...

  5. 采用Kruskal算法生成最小生成树,并采用并查集的合并优化和查询优化。

    文章目录 最小生成树 1.什么是图的最小生成树(MST)? 2.最小生成树用来解决什么问题? Kruskal(克鲁斯卡尔)算法 算法描述 图解 最小生成树 1.什么是图的最小生成树(MST)? 用N- ...

  6. Kruskal算法构造最小生成树

    问题[描述算法问题,首选形式化方式(数学语言),其次才是非形式化方式(日常语言)] 在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) ...

  7. Prim算法和Kruskal算法求最小生成树

    Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...

  8. Prim算法实现最小生成树(Java)

    最小生成树包含n个顶点和(n-1)条边,并且边的权重最小.Prim算法的思想是:由一颗小树慢慢长大,首先分为两个顶点集合,最小生成树的顶点集合A,和不在生成树中的顶点集合B,每次从B中找一个顶点v,使 ...

  9. 用kruskal算法求最小生成树各边的权值之和

    [问题描述] 已知含有n个顶点的带权连通无向图,采用邻接矩阵存储,邻接矩阵以三元组的形式给出, 只给出不包括主对角线元素在内的下三角形部分的元素,且不包括不相邻的顶点对.求该连通图的最小生成树中各边的 ...

  10. 图论 —— Kruskal 算法求最小生成树

    概述 Kruskal 算法是一种常见并且好写的最小生成树算法,由 Kruskal 发明.该算法的基本思想是从小到大加入边.算法实现基于贪心算法. 对于一个拥有 n n n 个顶点 m m m 条边的图 ...

最新文章

  1. zipimport.ZipImportError: can't decompress data; zlib not available 解决办法
  2. CSS实现 全兼容的多列均匀布局问题
  3. Cisco 设备设置监控口
  4. 使用Spring框架开发会遇到的所有异常及解决方案(持续更)
  5. 第四冠!腾讯AI「绝艺」斩获世界智能围棋公开赛冠军
  6. java robot 文档_文件配置 · simple-robot 机器人开发者使用文档 · 看云
  7. android app逆向分析,如何开始对Android应用的逆向分析?
  8. get请求可以传body吗_都9102年了,GET和POST的区别掌握了没有?
  9. Python 进程 Process 与线程 threading 区别 - Python零基础入门教程
  10. 面试题38 数字在排序数组中出现的次数
  11. 变量消元(Varible Elimination)和概率边缘化(Marginalization)的关系
  12. 用心筛选新股 追求利润最大化
  13. 解决conda install numpy 报错
  14. IC验证培训——实战SV验证学习(lab5)
  15. 团体程序设计天梯赛-练习集 L2-028 秀恩爱分得快 (25 分) (详细解法)
  16. C++开发工程师基础面试题
  17. 如何在智能手机上找到跟踪器
  18. h5压缩图片并上传到oss
  19. androidAPP接入微信分享【最新】
  20. 爱情树的html代码,index.html · RuanJiaFeng/爱情树 Html5实现唯美表白动画代码 - Gitee.com...

热门文章

  1. Objective-C 继承新的认识以及作用
  2. 费马大定理的启示:记笔记是一种信仰
  3. MYSQL 查看表定义的 4 种方法
  4. 触发器的创建及相关知识
  5. oracle表修改语句怎么写,Oracle修改表结构语句
  6. WIFI篇(2.python破解wifi--生成密码字典)
  7. storage 主机集群共享卷数据不同步_codis 高可用集群跳过nginx 代理
  8. matlab 频率分布直方图_小葱品题丨高考必考内容—频率分布直方图?!教你三步得满分!...
  9. mysql数据库官网怎么下载安装_MySQL数据库的下载与安装
  10. ubantu 安装anaconad_Ubuntu16.04安装Anaconda (转)