数据结构图之二(最小生成树--克鲁斯卡尔算法)
【1】克鲁斯卡尔算法
普里姆算法是以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树。
克鲁斯卡尔算法是直接以边为目标去构建。
因为权值是在边上,直接去找最小权值的边来构建生成树也是很自然的想法,只不过构建时要考虑是否会形成环路而已。
此时我们用到了图的存储结构中的边集数组结构。
以下是边集数组结构的定义代码:
本算法所用同普里姆算法的实例,我们直接创建图的边集数组。
并对边的权值从小到大排序后如下图:
【2】克鲁斯卡尔算法及详解
克鲁斯卡尔算法及其详解:
鉴于此算法很简单,当 i=0, i=1, i=2时执行结果可以眼观,不再赘述。直接分析重点:
此算法的Find函数由边数e决定,时间复杂度为O(loge),而外面有一个for循环e次。
所以克鲁斯卡尔算法的时间复杂度为O(eloge)
对比两个算法:
克鲁斯卡尔算法主要针对边展开,边数少时效率会很高,所以对于稀疏图有优势
而普利姆算法对于稠密图,即边数非常多的情况会好些。
【3】克鲁斯卡尔算法实现
实现代码如下:
1 #include <iostream> 2 using namespace std; 3 4 #define MAXVER 9 5 #define MAXEDGE 15 6 7 typedef struct Node 8 { 9 int begin; // 起点 10 int weight; // 权值 11 int end; // 末点 12 } edgeNode; 13 14 class Graph 15 { 16 private: 17 edgeNode edge[MAXEDGE]; 18 public: 19 Graph() 20 { 21 for (int i = 0; i < MAXEDGE; ++i) 22 { 23 edge[i].begin = edge[i].weight = edge[i].end = 0; 24 } 25 } 26 ~Graph() 27 {} 28 29 public: 30 void InsertSort() 31 { 32 for (int i = 0; i < MAXEDGE- 1; ++i) 33 { 34 if (edge[i+1].weight < edge[i].weight) 35 { 36 Node temp = edge[i+1]; 37 int j = i + 1; 38 do 39 { 40 edge[j] = edge[j-1]; 41 --j; 42 } while(j >= 0 && edge[j].weight > temp.weight); 43 44 edge[j+1] = temp; 45 } 46 } 47 } 48 49 istream & operator>>(istream &in) 50 { 51 int begin, value, end; 52 cout << "请输入15条边的起点 终点 权值:" << endl; 53 for (int i = 0; i < MAXEDGE; ++i) 54 { 55 in >> begin >> end >> value; 56 edge[i].begin = begin; 57 edge[i].weight = value; 58 edge[i].end = end; 59 } 60 return in; 61 } 62 ostream & operator<<(ostream &out) 63 { 64 // 插入排序 65 InsertSort(); 66 out << "输出排序边权值后信息:" << endl; 67 for (int i = 0; i < MAXEDGE; ++i) 68 { 69 out << "edge[" << i << "] " << edge[i].begin << " " << edge[i].weight << " " << edge[i].end << endl; 70 } 71 return out; 72 } 73 // 克鲁斯卡尔算法 74 void MiniSpanTree_Kruskal() 75 { 76 int i = 0, n = 0, m = 0; 77 int parent[MAXVER]; 78 for ( ; i < MAXVER; ++i) 79 parent[i] = 0; 80 for (i = 0; i < MAXEDGE; ++i) 81 { 82 n = Find(parent, edge[i].begin); 83 m = Find(parent, edge[i].end); 84 if (n != m) 85 { 86 parent[n] = m; 87 cout << " " << edge[i].begin << " " << edge[i].end << " " << edge[i].weight << endl; 88 } 89 } 90 } 91 92 int Find(int *parent, int f) 93 { 94 while (parent[f] > 0) 95 f = parent[f]; 96 return f; 97 } 98 }; 99 100 istream & operator>>(istream &in, Graph &g) 101 { 102 g >> in; 103 return in; 104 } 105 106 ostream & operator<<(ostream &out, Graph &g) 107 { 108 g << out; 109 return out; 110 } 111 112 void main() 113 { 114 Graph myg; 115 cin >> myg; 116 cout << myg; 117 myg.MiniSpanTree_Kruskal(); 118 } 119 // 备注: 120 // 最小生成树克鲁斯卡尔算法实现 121 // 整理于2013-12-04 122 // 测试需要输入: 123 /* 124 起始 终点 权值 125 0 1 10 126 0 5 11 127 1 2 18 128 1 8 12 129 1 6 16 130 2 8 8 131 2 3 22 132 3 8 21 133 3 6 24 134 3 7 16 135 3 4 20 136 4 7 7 137 4 5 26 138 5 6 17 139 6 7 19 140 */
View Code
Good Good Study, Day Day Up.
顺序 选择 循环 总结
转载于:https://www.cnblogs.com/Braveliu/p/3457872.html
数据结构图之二(最小生成树--克鲁斯卡尔算法)相关推荐
- 最小生成树克鲁斯卡尔算法
文章目录 一.什么是克鲁斯卡尔? 二.原理 三.代码实现 一.什么是克鲁斯卡尔? 克鲁斯卡尔算法是求连通网的最小生成树的另一种方法.与普里姆算法不同,它的时间复杂度为O(eloge)(e为网中的边数) ...
- 最小生成树------克鲁斯卡尔算法(数据结构)
树(Tree):如果一个无向连通图中不存在回路,则这种图称为树. 生成树 (Spanning Tree):无向连通图G的一个子图如果是一颗包含G的所有顶点的树,则该子图称为G的生成树. 生成树是连通图 ...
- 贪心算法(Greedy Algorithm)最小生成树 克鲁斯卡尔算法(Kruskal#39;s algorithm)
克鲁斯卡尔算法(Kruskal's algorithm)它既是古典最低的一个简单的了解生成树算法. 这充分反映了这一点贪心算法的精髓.该方法可以通常的图被表示.图选择这里借用Wikipedia在.非常 ...
- 最小生成树(克鲁斯卡尔算法)
关于克鲁斯卡尔算法他是针对边的.而普里姆算法是针对顶点的. 下面还是用普里姆算法的图. 如下: 因此可以构造边集数组. 如下图所示: 代码如下: int Find(int *parent, int f ...
- 最小生成树——克鲁斯卡尔算法
最小生成树的概念就不说了,本文主要是克鲁斯卡尔算法实现,而且用到了并查集思想.相较于prim算法,克鲁斯卡尔更容易理解:在不形成环的情况下,选取最小的权值边,直到点的个数减一.对于环的判断就使用并 ...
- USACO 3.1 Agri-Net 最短网络 (最小生成树)(克鲁斯卡尔算法)
题意 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助.约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场.为了用最 ...
- 最小生成树:克鲁斯卡尔算法+普里姆算法
目录 一.最小生成树 二.克鲁斯卡尔算法 1.思路 2.示例 3.C语言代码 三.普里姆算法 1.思路 2.C语言代码 一.最小生成树 一棵最小生成树需要满足哪些条件呢? 不存在回路 对于具有n个顶点 ...
- 最小生成树——普里姆算法和克鲁斯卡尔算法
最小生成树 用来解决工程中的代价问题. 一:普里姆算法 具体代码用C语言实现如下: typedef int VRType;typedef char InfoType;#define MAX_NAME ...
- 最小生成树算法普利姆算法和克鲁斯卡尔算法实现
最小生成树算法: 普里姆算法:顶点集合N,辅助顶点集合S,初始化中,将出发点vi加入S,并从N中删除 1.从顶点集合N中找到一条到集合S最近的边(vi,vj),存储该边,并将vj从N移到S中 2.重复 ...
最新文章
- 微众银行AI团队开源联邦学习框架,并发布《联邦学习白皮书1.0》
- leetcode 214. 最短回文串 解题报告
- chrome 插件开发各种功能demo_Chrome 开发者工具各种骚技巧
- go 语言系列(二)基本数据类型和操作符
- 注册中心ZooKeeper、Eureka、Consul 对比
- Collecting Bugs POJ - 2096(基础概率dp+期望模板)
- 胃癌2019csco指南_2019 CSCO胃癌诊疗指南精华来了!
- 「读懂源码系列3」lodash 是如何实现深拷贝的(上)
- 软考项目管理十大管理及过程
- 论文之生成对抗U-Net
- TTL和RS232之间的详细对比转
- Duplicate entry ‘‘ for key ‘Primary‘
- 目录-中文版Excel 2016宝典(第9版)
- 持续更新 iText in Action 2nd Edition中文版 个人翻译
- opc服务器连接plc断开显示,如何判断OPC与PLC通讯失败
- Allegro学习笔记:“如何建自己的Subclass”
- 【21天习惯养成记~~day17晚】
- 计算机主机光驱弹不出来怎么办,电脑dvd光驱打不开,光驱弹不出来解决
- VB6不能加载MSCOMCTL.OCX最简单的解决办法
- gr-gsm过程记录
热门文章
- Redis 21问,你接得住不?
- 一文读懂Java 11的ZGC为何如此高效
- 多线程访问共享对象和数据的方式
- Springboot+JPA 对应关系查询时导致的堆栈溢出 :java.lang.StackOverflowError:
- 请问为什么像cellspacing=0和bgcolor=red的属性在style里面不起作用呢?
- 配电基础知识汇总,99%的人都收藏了!
- 通信基站电源维护培训PPT课件
- 亚马逊部分 AWS DNS 系统遭 DDoS 攻击,已达数小时之久
- 机房做隔断为什么要用防火玻璃?
- html5 video标签不能播放视频,h5 video 视频不能正常播放