【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

数据结构图之二(最小生成树--克鲁斯卡尔算法)相关推荐

  1. 最小生成树克鲁斯卡尔算法

    文章目录 一.什么是克鲁斯卡尔? 二.原理 三.代码实现 一.什么是克鲁斯卡尔? 克鲁斯卡尔算法是求连通网的最小生成树的另一种方法.与普里姆算法不同,它的时间复杂度为O(eloge)(e为网中的边数) ...

  2. 最小生成树------克鲁斯卡尔算法(数据结构)

    树(Tree):如果一个无向连通图中不存在回路,则这种图称为树. 生成树 (Spanning Tree):无向连通图G的一个子图如果是一颗包含G的所有顶点的树,则该子图称为G的生成树. 生成树是连通图 ...

  3. 贪心算法(Greedy Algorithm)最小生成树 克鲁斯卡尔算法(Kruskal#39;s algorithm)

    克鲁斯卡尔算法(Kruskal's algorithm)它既是古典最低的一个简单的了解生成树算法. 这充分反映了这一点贪心算法的精髓.该方法可以通常的图被表示.图选择这里借用Wikipedia在.非常 ...

  4. 最小生成树(克鲁斯卡尔算法)

    关于克鲁斯卡尔算法他是针对边的.而普里姆算法是针对顶点的. 下面还是用普里姆算法的图. 如下: 因此可以构造边集数组. 如下图所示: 代码如下: int Find(int *parent, int f ...

  5. 最小生成树——克鲁斯卡尔算法

      最小生成树的概念就不说了,本文主要是克鲁斯卡尔算法实现,而且用到了并查集思想.相较于prim算法,克鲁斯卡尔更容易理解:在不形成环的情况下,选取最小的权值边,直到点的个数减一.对于环的判断就使用并 ...

  6. USACO 3.1 Agri-Net 最短网络 (最小生成树)(克鲁斯卡尔算法)

    题意 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助.约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场.为了用最 ...

  7. 最小生成树:克鲁斯卡尔算法+普里姆算法

    目录 一.最小生成树 二.克鲁斯卡尔算法 1.思路 2.示例 3.C语言代码 三.普里姆算法 1.思路 2.C语言代码 一.最小生成树 一棵最小生成树需要满足哪些条件呢? 不存在回路 对于具有n个顶点 ...

  8. 最小生成树——普里姆算法和克鲁斯卡尔算法

    最小生成树 用来解决工程中的代价问题. 一:普里姆算法 具体代码用C语言实现如下: typedef int VRType;typedef char InfoType;#define MAX_NAME ...

  9. 最小生成树算法普利姆算法和克鲁斯卡尔算法实现

    最小生成树算法: 普里姆算法:顶点集合N,辅助顶点集合S,初始化中,将出发点vi加入S,并从N中删除 1.从顶点集合N中找到一条到集合S最近的边(vi,vj),存储该边,并将vj从N移到S中 2.重复 ...

最新文章

  1. 微众银行AI团队开源联邦学习框架,并发布《联邦学习白皮书1.0》
  2. leetcode 214. 最短回文串 解题报告
  3. chrome 插件开发各种功能demo_Chrome 开发者工具各种骚技巧
  4. go 语言系列(二)基本数据类型和操作符
  5. 注册中心ZooKeeper、Eureka、Consul 对比
  6. Collecting Bugs POJ - 2096(基础概率dp+期望模板)
  7. 胃癌2019csco指南_2019 CSCO胃癌诊疗指南精华来了!
  8. 「读懂源码系列3」lodash 是如何实现深拷贝的(上)
  9. 软考项目管理十大管理及过程
  10. 论文之生成对抗U-Net
  11. TTL和RS232之间的详细对比转
  12. Duplicate entry ‘‘ for key ‘Primary‘
  13. 目录-中文版Excel 2016宝典(第9版)
  14. 持续更新 iText in Action 2nd Edition中文版 个人翻译
  15. opc服务器连接plc断开显示,如何判断OPC与PLC通讯失败
  16. Allegro学习笔记:“如何建自己的Subclass”
  17. 【21天习惯养成记~~day17晚】
  18. 计算机主机光驱弹不出来怎么办,电脑dvd光驱打不开,光驱弹不出来解决
  19. VB6不能加载MSCOMCTL.OCX最简单的解决办法
  20. gr-gsm过程记录

热门文章

  1. Redis 21问,你接得住不?
  2. 一文读懂Java 11的ZGC为何如此高效
  3. 多线程访问共享对象和数据的方式
  4. Springboot+JPA 对应关系查询时导致的堆栈溢出 :java.lang.StackOverflowError:
  5. 请问为什么像cellspacing=0和bgcolor=red的属性在style里面不起作用呢?
  6. 配电基础知识汇总,99%的人都收藏了!
  7. 通信基站电源维护培训PPT课件
  8. 亚马逊部分 AWS DNS 系统遭 DDoS 攻击,已达数小时之久
  9. 机房做隔断为什么要用防火玻璃?
  10. html5 video标签不能播放视频,h5 video 视频不能正常播放