【数据结构】最小生成树(Kruskal算法)

一.基本思想

 设无向连通网为G=(V,E),令G的最小生成树为T=(U,TE),其初态为U=V,TE={},然后,按照边的权值由小到大的顺序,考察G的边集E中的各条边。若被考察的边的两个顶点属于T的两个不同的连通分量,则将此边作为最小生成树的边加入到T中,同时把两个连通分量连接为一个连通分量;若被考察边的两个顶点属于同一个连通分量,则舍去此边,以免造成回路,如此下去,当T中的连通分量个数为1时,此连通分量便为G的一棵最小生成树。

二.两种最小生成树算法比较 

Prim算法:

对点做操作,维护一个在最小生成树中的点的顶点集U,以及一个待处理点的顶点集V-U,每次找出链接这两个集合的最短边,构成最小生成树,并将顶点加入集合U,知道所有顶点都处理完毕。

Kruskal算法:

对边做操作,每次选出一条最短边,如果它和当前最小生成树不构成回路就将其加入最小生成树,否则将其删除,知道所有边都处理完毕。

三.克鲁斯卡尔算法的伪代码描述

1.初始化

U=V;TE={}

2.重复下述操作直到T中的连通分量个数为1

        2.1 在E中寻找最短边(u,v);

        2.2 如果顶点u,v位于T的两个不同连通分量,则

                2.2.1 将边(u,v)并入TE;

                2.2.2 将这两个连通分量合为一个;

        2.3 标记边(u,v),使得(u,v)不参加后续最短边的选取

关键:如何判别被考察边的两个顶点是否位于两个连通分量

四.Kruskal算法需要解决的问题

1.图用哪种存储结构更合适?

如果采用邻接矩阵或者邻接表则需要搜索所有的边才能找到最短边

需要改进

2.边的排序问题

插入排序 O(n^2)

堆排序/快速排序 O(elog2e)

3.如何判别被考察边的两个顶点是否位于两个连通分量? 

所属的树是否有相同的根节点。

五.数据结构的设计

1.图的存储结构

        因为Kruskal算法是依次对图中的边进行操作,因此考虑边集数组存储图中的边,为了提高查找速度,将边集数组按边上的权排序。

const int MaxEdge=100;
struct EdgeType{int from,to;//边依附的两个顶点int weight;//边上的权值
};template <class T>
struct EdgeGraph{T vertex[MAX_VERTEX];//存放图顶点的数据EdgeType edge[MaxEdge];//存放边的数组int vertexNum,edgeNum;//图的顶点数和边数
};

2.连通分量

Kruskal算法实质上是使生成树以一种随意的方式生长,初始时,每个顶点构成一颗生成树。然后,每生长一次,就将两棵树合并,到最后合并成一棵树。

因此,可以设置一个数组parent[n],元素parent[i]表示顶点i的双亲结点,初始时,parent[i]=-1,表示顶点i没有双亲,即该结点是所在生成树的根节点;对于边(u,v),设vex1和vex2分别表示两个顶点所在树的根结点,如果vex1!=vex2,则顶点u和v必位于不同的连通分量,令parent[vex2]=vex1,实现将两棵树合并。

六.代码

template <class T>
void Kruskal(struct EdgeGraph<T> G){int i,num=0,vex1,vex2;//num用来记录生成树的边的条数int parent[G.vertexNum];for(i=0;i<G.vertexNum;i++){parent[i]=-1;//parent数组初始化}//对图G中的edge数组按照weight进行排序quickSort(G.edge, 0, G.edgeNum-1);for(i=0;i<G.edgeNum;i++){vex1=findRoot(parent, G.edge[i].from);vex2=findRoot(parent, G.edge[i].to);if(vex1!=vex2){outputMST(G.edge[i]);parent[vex2]=vex1;//合并生成树num++;if(num==G.vertexNum-1){return;}}}}
const int MaxEdge=100;
struct EdgeType{int from,to;//边依附的两个顶点int weight;//边上的权值
};template <class T>
struct EdgeGraph{T vertex[MAX_VERTEX];//存放图顶点的数据EdgeType edge[MaxEdge];//存放边的数组int vertexNum,edgeNum;//图的顶点数和边数
};template <class T>
void Kruskal(struct EdgeGraph<T> G);int findRoot(int parent[],int v){int t=v;while(parent[t]>-1){t=parent[t];}return t;
}int partition(EdgeType edge[],int first,int end);
void quickSort(EdgeType edge[],int first,int end);
void outputMST(EdgeType edge){cout<<"("<<edge.from<<","<<edge.to<<")"<<edge.weight<<endl;
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据Doris(二十八):Routine Load查看和修改作业

文章目录 Routine Load查看和修改作业 一、​​​​​​​查看导入作业状态

2023年【熔化焊接与热切割】免费试题及熔化焊接与热切割模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 熔化焊接与热切割免费试题是安全生产模拟考试一点通生成的&#xff0c;熔化焊接与热切割证模拟考试题库是根据熔化焊接与热切割最新版教材汇编出熔化焊接与热切割仿真模拟考试。2023年【熔化焊接与热切割】免费试题及…

用栈实现队列的功能,用队列实现栈的功能?

我们知道队列的特点是先入先出&#xff0c;栈的特点是后入先出&#xff0c;那么如何用栈实现队列的功能&#xff0c;又如何用队列实现栈的功能呢&#xff0c;且听我一一道来 我们首先来看用栈实现队列的功能&#xff0c;首先大伙儿要知道队列和栈的特点其实是“相反”&#xf…

OSG粒子系统与阴影-雾效模拟(1)

虚拟现实中有很多效果&#xff0c;如雨效、雪效、雾效等&#xff0c;这些都可以通过粒子系统来实现。一个真实的粒子系统的模式能使三维场景达到更好的效果。 本章对OSG粒子系统的使用以及生成自定义粒子系统的方法进行了详细介绍最后还附带说明了阴影的使用方法。在实时的场景…

电源控制系统架构(PCSA)之系统分区电源域

目录 4.2 电源域 4.2.1 电源模式 4.2.2 电源域的选择 4.2.3 系统逻辑 4.2.4 Always-On域 4.2.5 处理器Clusters 4.2.6 CoreSight逻辑 4.2.7 图像处理器 4.2.8 显示处理器 4.2.9 其他功能 4.2.10 电源域层次结构要求 4.2.11 SOC域示例 4.2 电源域 电源域在这里被定…

流程图是什么,用什么软件做?

在工作流程中&#xff0c;经常会遇到需要图形化呈现整个流程的情况。流程图就是一种一目了然的图形化表现方式&#xff0c;便于人们理解、沟通和管理整个流程。 1.Visio Visio是一款微软公司的图表软件&#xff0c;可以用于创建各种类型的流程图、组织结构图、网络图、平面图…

笔记:内网渗透流程之信息收集

信息收集 首先&#xff0c;收集目标内网的信息&#xff0c;包括子网结构、域名信息、IP地址范围、开放的端口和服务等。这包括通过主动扫描和渗透测试工具收集信息&#xff0c;以及利用公开的信息源进行信息搜集。 本机信息收集 查看系统配置信息 查看系统详细信息&#xf…

第一百七十八回 介绍一个三方包组件:SlideSwitch

文章目录 1. 概念介绍2. 使用方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"如何创建垂直方向的Switch"相关的内容&#xff0c;本章回中将 介绍SlideSwitch组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们…

linux -系统通用命令查询

有时候内网环境下&#xff0c;系统有些命令没有安装因此掌握一些通用的linux 命令也可以帮助我们解决一些问题查看 1.查看系统内核版本 uname -r2.查看系统版本 cat /etc/os-release3. 查看cpu 配置 lscpu4.查看内存信息 free [参数] 中各个数值的解释如下表 数值解释t…

基于51单片机电子钟万年历LCD1602显示

51单片机的电子钟万年历LCD1602显示 &#x1f534; &#x1f535;51单片机的电子钟万年历LCD1602显示&#x1f534; &#x1f535;主要功能&#xff1a;&#x1f534; &#x1f535;讲解视频&#x1f534; &#x1f535;仿真图&#xff1a;&#x1f534; &#x1f535;程序&…

python之pyqt专栏2-项目文件解析

项目结构 在上一篇文章python之pyqt专栏1-环境搭建&#xff0c;创建新的pyqt项目&#xff0c;下面我们来看一下这个项目下的文件。 从下面的文件结构图可以看到&#xff0c;该项目下有3个文件&#xff0c;untitled.ui,untitled.py 以及main.py。 QtDesigner可以UI界面的方式&am…

怎样自动把网页截图发到微信群里

现在很多公司都在使用企业微信了&#xff0c;不但方便公司内部交流和客户交流&#xff0c;还能组建各种小组群&#xff0c;业务群。企业微信群提供一个机器人的功能&#xff0c;方便我们把公司业务信息&#xff0c;或来自外部的信息自动发布到群里。 这里研究一下如何向微信群…