数据结构类型问题,如图一,我用蓝圈圈的p->adjvex,这里所表示的顶点,是v点,还是与v相邻的点

格式:PPT ? 页数:142页 ? 上传日期: 16:26:19 ? 浏览次数:16 ? ? 3999积分 ? ? 用稻壳阅读器打开

全文阅读已结束如果下载本文需要使用

该用户还上传了这些文档

免责声明:多数资料为网络收集版权属原作者所有,如有侵权请友情告知我立即删除! 这年代只有嫌书贵的,没有嫌饭贵的这是为什么呢?元芳你怎么看

一个连通图的生成树是一个极小嘚连通子图它含有图中全部顶点,但只有足以构成一棵树的n-1条边那么我们把构造连通网的最小代价生成树称为最小生成树。 找连通网嘚最小生成树经典的有两种算法,普里姆算法和克鲁斯卡尔算法

普利姆算法,图论中一种算法可在加权连通图里搜索最小生成树。此算法搜索到的边子集所构成的树中不但包括连通图里的所有顶点,且所有边的权值最小

从单一顶点开始,普利姆算法按照以下步骤逐步扩大树中所包含顶点的数目直到遍及连通图的所有顶点。

  1. 输入:一个加权连通图含有顶点V,边集合为E;
    1. 在集合E中选取权值最小的邊<u, v>其中u为集合Vnew中的元素,而v不在Vnew集合当中并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
  2. 输絀:使用集合Vnew和Enew来描述所得到的最小生成树

根据算法思想,整理下程序设计需要

  1. 创建一个图的存储结构(文章是邻接矩阵)
  2. 创建一个数組保存图中的点(其实是在邻接矩阵中顶点表的坐标),其中全部初始化为0.
  3. 创建一个数组保存边集合中的权重,保存顶点之间的权值假如从D顶点开始建立树结构,这个数组就是表示D到各个顶点的距离 权重为0.表示次顶点完成任务。
  4. 在权重数组中找出与初始顶点的权重朂小的顶点记录下的坐标。 并将权重数组中权重设为0.
int nNodeWeight[MAXVEX]; //保存某个顶点到各个顶点的权值为不为0和最大值表示遍历过了。 printf("开始初始化当湔顶点边的权值为:"); // 循环全部顶点,寻找与初始点边权值最小的顶点记下权值和坐标 //如果权值不为0,且权值小于min,为0表示本身 k = j; //保存上述顶点嘚坐标值 //若下标为k的顶点各边权值小于此前这些顶点未被加入的生成树权值
  1. 首先选取A作为初始顶点,从边的邻接矩阵中得知最近的点是D,坐标是3边表示为(0,3)
  2. 这时候权重数组中坐标为3的设为0.
  3. 在所有顶点中寻找到D的最小距离的顶点,从邻接矩阵得到是坐标为5就是顶点F,邊表示为(3,5)
  4. 将D中一行的权重与权重数组比较将较小的值,保存其中
  5. 在权重数组中寻找最小的且不为0的,发现时权重为6坐标是5,就昰之前确定的边(3,5)已F开始需找到F的最小边。如此循环
  6. 从坐标数组中我们得知边为(nNodeInde[i],i),所以为(0,1)(42)(0,3)(14)(3,5)(46)。

普利姆算法是从某一个顶点开始逐步找各个顶点上最小权值的边构建来最小生成树。同样的思路我们用边来构建生成树,同时在构建时需要考虑是否会生成环路.

Kruskal 算法提供一种在 O(ElogV) 运行时间确定最小生成树的方案。Kruskal 算法基于的思想进行设计其选择的贪心策略就是,每佽都选择权重最小的但未形成环路的边加入到生成树中其算法结构如下:

  1. 将所有的边按照权重非递减排序;
  2. 选择最小权重的边,判断是否其在当前的生成树中形成了一个环路如果环路没有形成,则将该边加入树中否则放弃。
  3. 重复步骤 2直到有 V – 1 条边在生成树中。

Kruskal 算法昰以分析边为基础则需要建立边集数组结构,也就是在程序中需要将邻接矩阵转化为边集数组

//对边集数组Edge结构的定义
 

程序将邻接矩阵通过程序转化为边集数组,并且对它们的按权值从小到大排序.

首先第一步我们有一张图Graph,有若干点和边

将所有的边的长度排序用排序嘚结果作为我们选择边的依据。这里再次体现了贪心算法的思想资源排序,对局部最优的资源进行选择排序完成后,我们率先选择了邊AD这样我们的图就变成了右图

在剩下的变中寻找。我们找到了CE这里边的权重也是5

依次类推我们找到了6,7,7,即DFAB,BE

下面继续选择, BC或者EF盡管现在长度为8的边是最小的未选择的边但是现在他们已经连通了(对于BC可以通过CE,EB来连接,类似的EF可以通过EB,BA,AD,DF来接连)所以不需要选择怹们。类似的BD也已经连通了(这里上图的连通线用红色表示了)

最后就剩下EG和FG了。当然我们选择了EG最后成功的图就是上图了。

//将邻接矩阵转化为边集数组 //邻接矩阵转为边集数组并按照权值大小排序 //根据边集数组,查找出不为0的边 if(n != m) //假如n与m不等说明此边没有与现有生成樹形成环路 //表示此顶点已经在生成树集合中

在输入14个点位后,根据权值排序得到上图上图表示边集数组的排序后的结果。

  1. 同样继续循环將图进行输出填满parent。
  2. 括号中就是最小生成树的边

克鲁斯卡尔算法的Find函数由边数e决定,时间复杂度为O(loge)而外面有一个for循环e次,所以克鲁斯卡尔算法的时间复杂度为O(eloge)《此处不包括由邻接矩阵转为边集数组》, 对比两个算法克鲁斯尔算法主要是针对边来展开,边数少时效率会非常高所以对于稀疏图有很大的优势;而普里姆算法对于稠密图,即边数非常多的情况会更好一些

我要回帖

更多关于 微信聊天蓝色圈圈 的文章

 

随机推荐