克鲁斯卡尔算法,是每次选出权值最小的边构成最小生成树,选出边时,要避免形成环。最终选出结点数减一条边即可。(避免形成环的问题,采用标号法(并查集),一开始,每个结各自为一个集合,分别给出各自不同大小的标号,选出的边的两端结点的标号将大的那个改成小的,以后选出的边的端点标号不能相同。)

#include<iostream>
#define N 100
int sum=0;//权值和
using namespace std;
//边节点
typedef struct vexnode {int adjvex;char v;struct  vexnode *nextarc;float info;
}ArNode;
typedef struct Vnode{  //顶点信息 char data;ArNode *firstarc; //指向第一个边结点
}Vonde,Adjust[100];
typedef struct {Adjust survice;//邻接表 int vexnum,acrnum;//图的当前顶点数和边数
}ALgraph;//邻接表查找int locate1(ALgraph&R, char v,int n){//找出字符为v的下标 int j,i;for(i=1;i<=n;i++){if(R.survice[i].data==v){j=i;}}return j;}
void creatUND(ALgraph &R){char v1,v2;//顶点的数据值 int i1,i2;//输入的两个顶点的位置和权值 float i3;//权值 printf("请输入顶点数和边数:"); cin>>R.vexnum>>R.acrnum; //输入顶点数和边数 printf("请输入各个顶点的值:\n"); for(int i=1;i<=R.vexnum;i++){cin>>R.survice[i].data;//输入各个顶点的信息 R.survice[i].firstarc=NULL;}printf("请输入每条边依附的两个结点和权值:\n");for(int i=1;i<=R.acrnum;i++){cin>>v1>>v2>>i3;i1=locate1(R,v1,R.vexnum);i2=locate1(R,v2,R.vexnum);ArNode *p=new ArNode;p->info=i3; //记录权值 p->v=v1;//记录边点的值 p->adjvex=i2;// 记录顶点的值 p->nextarc=R.survice[i2].firstarc; //利用头插法把第i1个的顶点插入到第i2个邻接表中 R.survice[i2].firstarc=p;//建立的邻接表表示的图为有向图,所以只记录一边,所以下面的部分代码给注释掉了 /*    ArNode *p1=new ArNode;p1->adjvex=i1;//记录顶点的位置 p1->info=i3;//记录权值 p1->v=v2;//记录边点的值 p1->nextarc=R.survice[i1].firstarc;R.survice[i1].firstarc=p1;// 将新节点*p2插入顶点Vi1的邻接表中 */} /* ArNode *p2; //这部分是将邻接表表示的图输出 for(int i=1;i<=R.vexnum;i++){p2=R.survice[i].firstarc;while(p2){printf("<%c , %c> : %.1f   ",R.survice[i].data,p2->v,p2->info);p2=p2->nextarc;}printf("\n");
}*/
}
//协助结构体,用来记录边的起始点,终点,权值信息
typedef struct end{char start;//边的起点 char end;//变得终点 int  w;//边的权值
}Edge[100]; //将边按照权值大小进行排序
void sort(Edge &E,ALgraph &R){char b;int num;int m=R.acrnum;for(int i=0;i<m ;i++){for(int j=0;j<m-i;j++){if(E[j+1].w<E[j].w){b=E[j+1].start;E[j+1].start=E[j].start;E[j].start=b;b=E[j+1].end;E[j+1].end=E[j].end;E[j].end=b;num=E[j+1].w;E[j+1].w=E[j].w;E[j].w=num;}}}}
//找出两结点的标号最大的那个
int  max(int i,int j){if(i>j){return i;}else return j;
}
//找出两结点的标号的小的那个
int min (int i,int j){if(i<j){return i;}else return j;
}
void minspantree_Kruskal(ALgraph &G,Edge &E){int u=0; //数组Edge的下标 int parent[G.vexnum+1];//标号用的数组 for(int i=1;i<=G.vexnum;i++){//将他们分成不同的集合 parent[i]=i;}ArNode *p1; //临结点的指针 for(int i=1;i<=G.vexnum;i++){ //将每条边的起点和终点,权值赋予结构体中EDGE中 p1=G.survice[i].firstarc; while(p1){ E[u].start=G.survice[i].data;E[u].end=p1->v;E[u].w=p1->info;u++;p1=p1->nextarc;}}sort(E,G); //将每条边按照权值的大小排序int n=0;//要挑选出边的下标 for(int i=0;i<=G.vexnum-1;i++){//边的结构体下标是从零开始的 char head1 =E[n].start;//记录选出边的起始点 char end1 =E[n].end;//记录选出边的终点 if(parent[locate1(G,head1,G.vexnum)]!=parent[locate1(G,end1,G.vexnum)]){// 如果结点的标号不相等的话,将权值加上 sum+=E[n].w; int  maxv=max(parent[locate1(G,head1,G.vexnum)],parent[locate1(G,end1,G.vexnum)]);//得到边两端结点标号的最大值 int  minv=min(parent[locate1(G,head1,G.vexnum)],parent[locate1(G,end1,G.vexnum)]);//得到边两端结点标号的最小值 parent[locate1(G,head1,G.vexnum)]=minv;  parent[locate1(G,end1,G.vexnum)]=minv;//他俩选出后成为一个集合,将标号都改为最小值 for (int j=1;j<=G.vexnum;j++){//将结点中所有标号都为边两端标号最大值的结点标号都改为最小值 if(parent[j]==maxv){parent[j]=minv;}}printf("<%c ,%c> \n",head1,end1); //输出找出变的两个结点 }n++;} printf("最小权值之和为:%d",sum); }
int main (){ALgraph R;Edge E;//有关边的结构体 creatUND(R);minspantree_Kruskal(R,E);return 0;
} 

克鲁斯卡尔算法建立最小生成树相关推荐

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

    1.克鲁斯卡尔算法 克鲁斯卡尔算法的核心思想是从边集出发,逐步把代价最小且不与已经加到最小生成树的边集构成回路的边加入到最小生成树的边集中,直到求出构成最小生成树的n-1边(n是图的顶点数).算法的基 ...

  2. 利用克鲁斯卡尔算法求最小生成树

    思路:最小生成树即为无向连通图G的一个子图如果是一颗包含G的所有顶点且权最小的树则称为最小生成树.克鲁斯卡尔算法的基本思想是以边为主导地位,始终选择当前可用的(所选的边不能构成回路)最小权值边.所以第 ...

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

    克鲁斯卡尔算法的介绍 1)克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 2)基本思想:按照权值从小到大的顺序选择 n-1条边,并保证这 n-1条边不构成回路 3)具体做法: ...

  4. 普利姆算法和克鲁斯卡尔算法求解最小生成树

    Q:最小生成树有什么用? A:譬如我要去五个城市旅游,每两个城市之间可能有路也可能没有,路的距离可能一样也可能不一样,随机从一个城市出发,我想要把每个城市走一遍,怎么样走过的路距离最短,比如我想从上海 ...

  5. 编程中十大常用算法:(七)克鲁斯卡尔算法(最小生成树)

    介绍 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想: 按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路 具体做法: 首先构造一个只含n个顶点的森 ...

  6. 1201-2019-算法-克鲁斯卡尔算法(最小生成树MST-Kruskal算法)

    ① Kruskal算法先对路径的权值进行排序 ② 再在图中加入这个路径(要求不产生回路). 关键就是不能形成回路.判断是否为回路的准则是:两个顶点例如(C-E)是否有同一个终点. 关键代码:关键代码是 ...

  7. 最小生成树(普里姆算法【Prim】与克鲁斯卡尔算法【Kruskal】)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

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

    目录 最小生成树 普利姆算法 算法介绍 代码 克鲁斯卡尔算法 算法介绍 步骤解析 回路 代码实现 最小生成树主要是用于解决修路问题等类似问题,要将所有顶点连通,并且权值之和最小. 最小生成树 给定一个 ...

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

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

最新文章

  1. (转)动态SQL和PL/SQL的EXECUTE IMMEDIATE选项
  2. 直正的互联网产品设计:七个作为产品经理实际上很重要的”小事“
  3. 北斗导航 | RAIM:单差载波相位完好性监测(接收机自主完好性检测)
  4. Druid 数据源连接池配置
  5. ASP.NET的MVC请求处理流程
  6. HDU ACM 3986 Harry Potter and the Final Battle(邻接表实现最短路dijkstra堆优化记录路径 + 枚举最短路上每条边)...
  7. systemctl命令_开发者必备Linux命令
  8. c# 盖尔-沙普利算法的改进
  9. iMX8MM u-boot2021.04移植
  10. 服务器 '' 上的 MSDTC 不可用。
  11. 对称加密算法原理简介
  12. html5课程总结500字,体育课心得体会500字(精选6篇)
  13. 未授权访问漏洞原理及复现
  14. 随笔二——JavaScript脚本语言
  15. arcpy——利用Arcpy进行字段操作
  16. 【MATLAB教程案例3】QPSK解调过程的MATLAB开发
  17. 网站常用邮箱找回密码流程插件页面
  18. 基因组特征评估——k-mer analysis
  19. 90后男生全款4万买房移居鹤岗
  20. c语言 数据溢出时会输出什么

热门文章

  1. python链家新房信息获取练习
  2. FPGA——DAC驱动
  3. 【区块链】交易平台安全审计项
  4. oppoR9m降级 root刷机 Magiskroot 解锁system文件夹
  5. 杨广悟道第一课:年月日时天干地支的计算方法
  6. 中国医科大学2021年9月《药事管理学》作业考核试题
  7. 联想和戴尔的渠道之争
  8. 【GBase 8a MPP数据库集群】函数DECODE
  9. druid 大量sleep连接
  10. 火影抽卡模拟器1.0.2