Kruskal算法

  • Kruskal的由来
    Prim算法利用了MST的性质:假设N= (V,E)是一个连通图,U是顶点集V的一个非空子集,若(u,v)是一条最小权值的边,其中u属于U,v属于V-U,则必存在一颗包含(u,v)的最小生成树。

  • Kruskal算法的实现
    克鲁斯卡尔算法的构造过程
    假设连通网N=(V, E),将N中的边按权值从小到大的顺序排列。

    ①初始状态为只有n个顶点而无边的非连通图T=(v, {}),图中每个顶点自成一个连通分量。

    ②在E中选择权值最小的边,若该边依附的顶点落在 中不同的连通分量上(即不形成间路),则将此边加入到工中,否则舍去此边而选择下一条权值最小的边。

    (3) 重复②,直至T中所有顶点都在同一连通分量上为止。
    辅助数组

     //辅助数组typedef struct{string head;//边的起点string tail;//边的终点int weight;//边的权值}Edge[MVNum],EDGE;int VexSet[MVNum];//标识各个顶点所属的连通分量//辅助数组

图例

  • Kruskal算法的实现步骤
    (1)将数组Edge中的元素按权值从小到大排序。
    (2)依次查看数组Edge中的边,循环执行一下操作:

    • 依次从排好序的数组Edge中选出一条边(U1,U2);

    • 在Vexset中分别查找v1,v2所在的连通分量vs1 vs2,进行判断;

      • 如果vs1 vs2不等,表明所选的两个顶点所属不同的连通分量,输出此边,并合并vs1 vs2的连通分量。(也就是没有形成闭环)

      • 如果vs1 vs2相等,表明所选的两个顶点属于同一个连通分量属于同一个连通分量,舍去此边而选择下一条权值最小的边。(形成了闭环)

  • 运行结果

  • 实现代码
    (邻接矩阵和邻接表分别实现)

 #include<iostream>#include<string>using namespace std;#define OK 1#define ERROR 0#define MAXint 32767 //表示无穷大#define MVNum 100  //最大顶点数//邻接矩阵的结构typedef struct{string vexs[MVNum];//顶点表int arcs[MVNum][MVNum];//邻接矩阵,也就是表示边的权值int vexnum, arcnum;//图的顶点数和边的个数}AMGraph;//邻接矩阵的结构//邻接表的结构typedef struct ArcNode {//边结点int adjvex;//该边所指向的顶点的位置struct  ArcNode* nextarc;//指向下一条边的指针int info;//和边相关的信息}ArcNode;typedef struct {//顶点信息string data;ArcNode* firstarc;//指向第一条依附该顶点的边的指针}VNode, AdjList[MVNum];typedef struct//邻接表{AdjList vertices;//顶点信息int vexnum, arcnum;//图的当前顶点数和边数}ALGraph;//邻接表的结构int Locate(ALGraph G, string v)//Locate重载{for (int i = 0; i < G.vexnum; i++){if (G.vertices[i].data == v){return i;}}return -1;}//辅助数组typedef struct{string head;//边的起点string tail;//边的终点int weight;//边的权值}Edge[MVNum],EDGE;int VexSet[MVNum];//标识各个顶点所属的连通分量//辅助数组Edge edge;//查询结点位置int Locate(AMGraph G, string v){for (int i = 0; i < G.vexnum; i++){if (G.vexs[i] == v){return i;}}return -1;}//查询结点位置//创建邻接矩阵int CreateUDN(AMGraph& G)//无向图的构造{cout << "请输入图的顶点数和边数:";cin >> G.vexnum >> G.arcnum;cout << "请输入各点的信息:";for (int i = 0; i < G.vexnum; i++){cin >> G.vexs[i];}for (int i = 0; i < G.vexnum; i++)//初始化边的权值为MAXINT{for (int j = 0; j < G.vexnum; j++){G.arcs[i][j] = MAXint;}}cout << "各边的顶点信息和权值:";for (int k = 0; k < G.arcnum; k++)//构造邻接矩阵{string v1, v2;int w;//边的两个顶点以及权值cin >> v1 >> v2 >> w;edge[k] = { v1,v2,w };int i = Locate(G, v1);//找到点的位置int j = Locate(G, v2);G.arcs[i][j] = w;//赋予权值G.arcs[j][i] = G.arcs[i][j];}return OK;}//创建邻接矩阵//创建邻接表int CreateUDG(ALGraph& G){cout << "请输入图的顶点数和边数:";cin >> G.vexnum >> G.arcnum;//输入顶点数和边数cout << "请输入各顶点的信息:";for (int i = 0; i < G.vexnum; i++)//初始化顶点信息{cin >> G.vertices[i].data;//输入顶点的信息G.vertices[i].firstarc = NULL;//firstarc置空}cout << "请输入各边的两顶点信息和权值:";for (int k = 0; k < G.arcnum; k++){string v1, v2;int weight;//权值cin >> v1 >> v2 >> weight;//输入一条边依附的两个顶点edge[k] = { v1,v2,weight };int i = Locate(G, v1);int j = Locate(G, v2);ArcNode* p1 = new ArcNode;p1->info = weight;p1->adjvex = j;p1->nextarc = G.vertices[i].firstarc;G.vertices[i].firstarc = p1;ArcNode* p2 = new ArcNode;p2->info = weight;p2->adjvex = i;p2->nextarc = G.vertices[j].firstarc;G.vertices[j].firstarc = p2;}return OK;}//创建邻接表void Sort(Edge &edge,int len){for (int i = 0; i < len-1; i++){for (int j = i + 1; j < len; j++){if (edge[i].weight > edge[j].weight){EDGE d = edge[i];edge[i] = edge[j];edge[j] = d;}}}}//Kruskal最小生成树void MiniSpanTree_Kruskal(AMGraph G){Sort(edge, G.arcnum);//将数组edge中的元素按权值大小从小到大排序for (int i = 0; i < G.vexnum; i++)//辅助数组,表示各顶点自成一个连通分量{VexSet[i] = i;}for (int i = 0; i < G.arcnum; i++){int head = Locate(G, edge[i].head);//head为边的始点Head的下标int tail = Locate(G, edge[i].tail);//tail为边的始点Tail的下标int v1 = VexSet[head];//获取边Edge[i]的始点所在的连通分量int v2 = VexSet[tail];//获取边Edge[i]的始点所在的连通分量if (v1 != v2)//边的两个顶点分属不同的连通分量{cout << edge[i].head << "-" << edge[i].tail << endl;//输出边的信息for (int j = 0; j < G.vexnum; j++)//合并连通分量{if (VexSet[j] == v2){VexSet[j] = v1;}}}}}//Kruskal最小生成树//Kruskal最小生成树void MiniSpanTree_Kruskal(ALGraph G){Sort(edge, G.arcnum);//将数组edge中的元素按权值大小从小到大排序for (int i = 0; i < G.vexnum; i++)//辅助数组,表示各顶点自成一个连通分量{VexSet[i] = i;}for (int i = 0; i < G.arcnum; i++){int head = Locate(G, edge[i].head);//head为边的始点Head的下标int tail = Locate(G, edge[i].tail);//tail为边的始点Tail的下标int v1 = VexSet[head];//获取边Edge[i]的始点所在的连通分量int v2 = VexSet[tail];//获取边Edge[i]的始点所在的连通分量if (v1 != v2)//边的两个顶点分属不同的连通分量{cout << edge[i].head << "-" << edge[i].tail << endl;//输出边的信息for (int j = 0; j < G.vexnum; j++)//合并连通分量{if (VexSet[j] == v2){VexSet[j] = v1;}}}}}int main(){ALGraph G;CreateUDG(G);cout << "请输入最小生成树的起点";string v;cin >> v;MiniSpanTree_Kruskal(G);return 0;}

Kruskal算法 最小生成树相关推荐

  1. 求的带权图最小生成树的Prim算法和Kruskal算法

    求的带权图最小生成树的Prim算法和Kruskal算法 最小生成树的概念 最小生成树其实是最小权重生成树的简称. 一个连通图可能有多个生成树.当图中的边具有权值时,总会有一个生成树的边的权值之和小于或 ...

  2. Kruskal求最小生成树

    Kruskal算法最小生成树 #include <iostream> #include <cstdio> #include <cstring> #include & ...

  3. 数据结构与算法(7-3)最小生成树(普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法)

    目录 一.最小生成树简介 二.普里姆算法(Prim) 1.原理 2.存储 2-1.图顶点和权: 2-3. 最小生成树: 3.Prim()函数 3-1.新顶点入树 3-2.保留最小权 3-3. 找到最小 ...

  4. 【数据结构】最小生成树 Prim算法 Kruskal算法

    最小生成树应用场景: 假设以下场景,有一块木板,板上钉上一些钉子,这些钉子可以由一些细绳连接起来.假设每个钉子可以通过一根或者多根细绳连接起来,那么一定存在这样得情况,即用最少的细绳把所有的钉子连接起 ...

  5. ds图—最小生成树_Java: Kruskal算法生成最小生成树(邻接矩阵)

    Java: Kruskal算法生成最小生成树(邻接矩阵): package 输出: Kruskal=36: (E,F) (C,D) (D,E) (B,F) (E,G) (A,B) 分析: Java: ...

  6. 生成树的概念,最小生成树Prim算法 Kruskal算法

    求解最小生成树可以用Prim算法 Kruskal算法

  7. Kruskal算法构造最小生成树

    问题[描述算法问题,首选形式化方式(数学语言),其次才是非形式化方式(日常语言)] 在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) ...

  8. Prim算法和Kruskal算法求最小生成树

    Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...

  9. 生成随机数放入整型数组怎么判断有没有重复_图的应用(1)-连通图的最小生成树(Prim算法和Kruskal算法)...

    连通图的生成树: 是一个极小的连通图,它含有图中全部的N个顶点,但是只足以构成一颗树的N-1条边. 必须满足三个条件: 图是连通图: 图中包含了N个结点 图中边的数量等于N-1条. 连通图生成树的判断 ...

最新文章

  1. linux开机启动项6个级别_linux开机启动设置的几种方法
  2. 10秒完成Linux系统pip在线安装
  3. 数据结构与算法 | 带头双向循环链表
  4. 华为9月将带来鸿蒙系统2.0;张勇任阿里巴巴董事长后发布首封致股东信;iOS 14首个公测版发布​| 极客头条
  5. SQL进阶教程(一)——CASE表达式
  6. c 程序设计语言简单列子,C语言程序设计实例大全(220个例子)
  7. windows清理缓存性能加速
  8. 台式计算机运行慢怎么样能提高速度,怎样提高电脑运行速度,教您怎样提高电脑运行速度...
  9. Itext导出pdf教程
  10. 散布谣言也能实现一致性?来看看Gossip协议如何活用六度分隔理论
  11. blackbox_exporter 黑盒监测
  12. 读书笔记《深度学习与图像识别原理与实践 大白话讲解对小白易懂》2022-8-5
  13. 文章阅读 - 机器学习检测DNS隧道
  14. std::tr1::bind使用帮助
  15. 叫谁修猫呢?叫蓝总|ONES 人物
  16. 打游戏哪种蓝牙耳机比较好?适合玩游戏的无线蓝牙耳机
  17. 怎么查看电脑内存的型号
  18. 先學30天jQuery再說之属性操作 - .contains() 方法和 :contains 选择器(par7)
  19. Overleaf提示Misplaced alignment tab character .
  20. 解决由于找不到amd_ags_x64.dll,无法继续执行代码。重新安装程序可能会解决此问题,地平线(Forza Horizon 5)

热门文章

  1. k8s核心技术-Ingress(对外暴露应用实施)---K8S_Google工作笔记0042
  2. MyCat分布式数据库集群架构工作笔记0004---Mycat的实现原理
  3. VB.NET工作笔记008---vs2017创建使用WCF服务_并调用服务demo
  4. 超高并发优化技能001--隔离
  5. Android学习笔记---26_采用JSON格式返回数据给资讯客户端,效率上要高于xml文件解析和传输
  6. error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int错误的解决方法
  7. 2015年6月24日日报
  8. 什么是 C Runtime 函数库
  9. 经典算法研究系列:七、深入浅出遗传算法,透析GA本质【转载】
  10. ap sat_收藏丨2020年雅思、托福、GRE、SAT、ACT、AP考试时间汇总