图解最小生成树 - 克鲁斯卡尔(Kruskal)算法
我们在前面讲过的《克里姆算法》是以某个顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树的。同样的思路,我们也可以直接就以边为目标去构建,因为权值为边上,直接找最小权值的边来构建生成树也是很自然的想法,只不过构建时要考虑是否会形成环而已,此时我们就用到了图的存储结构中的边集数组结构,如图7-6-7
假设现在我们已经通过邻接矩阵得到了边集数组edges并按权值从小到大排列如上图。
下面我们对着程序和每一步循环的图示来看:
算法代码:(改编自《大话数据结构》)
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
typedef struct
{ int begin; int end; int weight; } Edge; /* 查找连线顶点的尾部下标 */ return f; Edge edges[MAXEDGE];/* 定义边集数组,edge的结构为begin,end,weight,均为整型 */ /* 此处省略将邻接矩阵G转换为边集数组edges并按权由小到大排列的代码*/ cout << "打印最小生成树:" << endl; cout << "(" << edges[i].begin << ", " << edges[i].end << ") " } |
1、程序 第17~28行是初始化操作,中间省略了一些存储结构转换代码。
2、第30~42行,i = 0 第一次循环,n = Find( parent, 4) = 4; 同理 m = 7; 因为 n != m 所以parent[4] = 7, 并且打印 “ (4, 7) 7 ” 。此时我们已经将边(v4, v7)纳入到最小生成树中,如下图的第一个小图。
3、继续循环,当i从1 至 6 时,分别把(v2, v8), (v0, v1), (v0, v5), (v1, v8), (v3, v7), (v1, v6)纳入到最小生成树中,如下图所示,此时parent数组为
{ 1, 5, 8, 7, 7, 8, 0, 0, 6 },如何解读现在这些数字的意义呢?从图i = 6来看,其实是有两个连通的边集合A与B 纳入到最小生成树找中的,如图7-6-12所示。parent[0] = 1表示v0 和v1 已经在生成树的边集合A中,将parent[0] = 1中的 1 改成下标,由parent[1]
= 5 ,表示v1 和v5 已经在生成树的边集合A中,parent[5] = 8 ,表示v5 和v8 已经在生成树的边集合A中,parent[8]
= 6 ,表示v8 和v6 已经在生成树的边集合A中,parent[6] =
0 表示集合A暂时到头,此时边集合A有 v0, v1, v5, v6, v8。查看parent中没有查看的值,parent[2] = 8,表明v2 和 v8在一个集合中,即A中。再由parent[3] = 7, parent[4] = 7 和 parent[7] = 0 可知v3, v4, v7 在一个边集合B中。
4、当i = 7时, 调用Find函数,n = m = 6,不再打印,继续下一循环,即告诉我们,因为(v5, v6) 使得边集合A形成了回路,因此不能将其纳入生成树中,如图7-6-12所示。
5、当i = 8时与上面相同,由于边(v1, v2) 使得边集合A形成了回路,因此不能将其纳入到生成树中,如图7-6-12所示。
6、当i = 9时,n = 6, m = 7, 即parent[6] = 7,打印“(6, 7)19” ,此时parent数组为{ 1, 5, 8, 7, 7, 8, 7, 0, 6 } ,如图7-6-13所示。
最后,我们来总结一下克鲁斯卡尔算法的定义:
假设 N = (V, {E}
)是连通网,则令最小生成树的初始状态为只有n个顶点而无边的非连通图T { V, {}
},图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点落在T中不同的连通分量上,则将其加入到 T
中,否则舍去此边而选择下一条代价最小的边。依次类推,直至T中所有顶点都在同一连通分量上为止。
此算法的Find函数由边数e决定,时间复杂度为O(loge),而外面有一个for循环e次,所以克鲁斯卡尔算法的时间复杂度为O(eloge)。
对比普里姆和克鲁斯卡尔算法,克鲁斯卡尔算法主要针对边来展开,边数少时效率比较高,所以对于稀疏图有较大的优势;而普里姆算法对于稠密图,即边数非常多的情况下更好一些。
图解最小生成树 - 克鲁斯卡尔(Kruskal)算法的更多相关文章
- 洛谷P3366【模板】最小生成树-克鲁斯卡尔Kruskal算法详解附赠习题
链接 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边.(N<=5000,M&l ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- 克鲁斯卡尔(Kruskal)算法求最小生成树
/* *Kruskal算法求MST */ #include <iostream> #include <cstdio> #include <cstring> #inc ...
- 克鲁斯卡尔(Kruskal)算法
# include <stdio.h> # define MAX_VERTEXES //最大顶点数 # define MAXEDGE //边集数组最大值 # define INFINITY ...
- 图->连通性->最小生成树(克鲁斯卡尔算法)
文字描述 上一篇博客介绍了最小生成树(普里姆算法),知道了普里姆算法求最小生成树的时间复杂度为n^2, 就是说复杂度与顶点数无关,而与弧的数量没有关系: 而用克鲁斯卡尔(Kruskal)算法求最小生成 ...
- 最小生成树——Kruskal(克鲁斯卡尔)算法
[0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 Kruskal(克鲁斯卡尔)算法 的idea 并用 源代码加以实现: 0.2)最小生成树的基础知识,参见 ...
- 最小生成树之Prim Kruskal算法(转)
最小生成树 首先,生成树是建立在无向图中的,对于有向图,则没有生成树的概念,所以接下来讨论的图均默认为无向图.对于一个有n个点的图,最少需要n-1条边使得这n个点联通,由这n-1条边组成的子图则称为原 ...
- 贪心算法(Greedy Algorithm)之最小生成树 克鲁斯卡尔算法(Kruskal's algorithm)
克鲁斯卡尔算法(Kruskal's algorithm)是两个经典的最小生成树算法的较为简单理解的一个.这里面充分体现了贪心算法的精髓.大致的流程能够用一个图来表示.这里的图的选择借用了Wikiped ...
- 贪心算法(Greedy Algorithm)最小生成树 克鲁斯卡尔算法(Kruskal's algorithm)
克鲁斯卡尔算法(Kruskal's algorithm)它既是古典最低的一个简单的了解生成树算法. 这充分反映了这一点贪心算法的精髓.该方法可以通常的图被表示.图选择这里借用Wikipedia在.非常 ...
随机推荐
- [转贴]SSL工作原理
SSL协议使用不对称加密技术实现会话双方之间信息的安全传递.可以实现信息传递的保密性.完整性,并且会话双方能鉴别对方身份.不同于常用的http协议,我们在与网站建立SSL安全连接时使用https协议, ...
- c++ placement new概念
参考:http://www.cnblogs.com/Clingingboy/archive/2013/04/26/3044910.html 转:http://bbs.chinaunix.net/thr ...
- DataTrigger
<ListView Name="lvStatus" MinHeight="120" Grid.Row="2"> <List ...
- 【pyhon】理想论坛爬虫1.05版,将读取和写DB分离成两个文件
下午再接再厉仿照Nodejs版的理想帖子爬虫把Python版的也改造了下,但美中不足的是完成任务的线程数量似乎停滞在100个左右,让人郁闷.原因还待查. 先把代码贴出来吧,也算个阶段性成果. 爬虫代码 ...
- leetcode笔记:Sqrt(x)
一. 题目描写叙述 Implement int sqrt(int x). Compute and return the square root of x. 二. 题目分析 该题要求实现求根公式,该题还 ...
- C++ Linux 多线程之创建、管理线程
线程就是,在同一程序同一时间内同意运行不同函数的离散处理队列. 这使得一个长时间去进行某种特殊运算的函数在运行时不阻碍其它的函数变得十分重要. 线程实际上同意同一时候运行两种函数,而这两个函数不必相互 ...
- C语言高速入门系列(二)
C语言高速入门系列(二) -----转载请注明出处coder-pig 本节引言: 在前面一节中我们对C语言进行了初步的了解,学会了使用IDE进行代码的编写,编译执行! 在这一节中我们会对C语言的基本的 ...
- activemq无法启动且后台管理界面进不去的解决办法
从官网下载了一个最新的activemq,目前最新版本是5.14.5 我下载的是windows版本,通过执行%activemq home%/bin/win64/InstallService.bat,可以 ...
- TQ2440 LCD试验失败经验教训
试验环境:TQ2440开发板(配套TQ4.3寸屏) 试验参考书目:<ARM处理器裸机开发实战--机制而非策略>(以下简称<裸机开发实战>) <裸机开发实战>第13章 ...
- 关于csdn博客中案例效果的动态演示
在曾经一篇博文中,网友评论说要是案例效果是动态演示的就好了,我认为说的非常是有道理.由于一个简单的截图不能非常好的展示案例效果.要是有一张gif图能动态的播放案例效果就再好只是了.在这里提供一个小软件 ...