克鲁斯卡尔算法与普里姆算法详解
最近数据结构老师讲了好几个算法,今晚上正好有空,所以就来整理一下
一:Kruskal算法思想:直接以边为目标去构建最小生成树,注意只找出n-1条边即可,并且不能形成回路。图的存储结构采用的是边集数组,且权值相等的边在数组中的排练次序是任意的,如果图中的边数较多则此算法会很浪费时间!
二:Prim算法思想:以某一顶点为起点,一点一点的去找各顶点上最小权值的边来构建最小生成树。图的存储结构是邻接矩阵,此方法需要一个顶点集合T,开始的时候为空集,慢慢的会将连通的顶点陆续的加入到集合中,全部顶点都加入集合以后,就得到我们所需要的最小生成树啦!
三:克鲁斯卡尔算法代码实现方法一:
#include "stdio.h"
#include "stdlib.h"
struct edge
{int m;int n;int d;
}a[5010]; //克鲁斯卡尔算法采用边集数组来存储图int cmp(const void *a,const void *b) //按升序排列,此过程也可以用快排来实现!
{return ((struct edge *)a)->d>((struct edge *)b)->d;
}int main(void)
{int i,n,t,num,min,k,g,x[100];printf("请输入顶点的个数:");scanf("%d",&n);t=n*(n-1)/2; //n个顶点的无向连通图共有n*(n-1)/2条边for(i=1;i<=n;i++)x[i]=i;printf("请输入每条边的起始端点、权值:/n");for(i=0;i<t;i++)scanf("%d %d %d",&a[i].m,&a[i].n,&a[i].d); //输入每条边的权值qsort(a,t,sizeof(a[0]),cmp);//此过程可以用快排,来将每条边权值从小到大排列起来min=num=0;for(i=0;i<t && num<n-1;i++){for(k=a[i].m;x[k]!=k;k=x[k]) //判断线段的起始点所在的集合x[k]=x[x[k]];for(g=a[i].n;x[g]!=g;g=x[g]) //判断线段的终点所在的集合x[g]=x[x[g]];if(k!=g) //如果线段的两个端点所在的集合不一样{x[g]=k;min+=a[i].d;num++;printf("最小生成树中加入边:%d %d/n",a[i].m,a[i].n);}}printf("最小生成树的权值为:%d/n",min);system("pause");return 0;
}
克鲁斯卡尔算法代码实现方法二:
typedef struct
{ char vertex[VertexNum]; //顶点表 int edges[VertexNum][VertexNum]; //邻接矩阵,可看做边表 int n,e; //图中当前的顶点数和边数
}MGraph; typedef struct node
{ int u; //边的起始顶点 int v; //边的终止顶点 int w; //边的权值
}Edge; void kruskal(MGraph G)
{ int i,j,u1,v1,sn1,sn2,k; int vset[VertexNum]; //辅助数组,判定两个顶点是否连通 int E[EdgeNum]; //存放所有的边 k=0; //E数组的下标从0开始 for (i=0;i<G.n;i++) { for (j=0;j<G.n;j++) { if (G.edges[i][j]!=0 && G.edges[i][j]!=INF) { E[k].u=i; E[k].v=j; E[k].w=G.edges[i][j]; k++; } } } heapsort(E,k,sizeof(E[0])); //堆排序,按权值从小到大排列 for (i=0;i<G.n;i++) //初始化辅助数组 { vset[i]=i; } k=1; //生成的边数,最后要刚好为总边数 j=0; //E中的下标 while (k<G.n) { sn1=vset[E[j].u]; sn2=vset[E[j].v]; //得到两顶点属于的集合编号 if (sn1!=sn2) //不在同一集合编号内的话,把边加入最小生成树 {printf("%d ---> %d, %d",E[j].u,E[j].v,E[j].w); k++; for (i=0;i<G.n;i++) { if (vset[i]==sn2) { vset[i]=sn1; } } } j++; }
}
四:Prim算法具体实现
#define MAX 100000
#define VNUM 10+1 //这里没有ID为0的点,so id号范围1~10int edge[VNUM][VNUM]={/*输入的邻接矩阵*/};
int lowcost[VNUM]={0}; //记录Vnew中每个点到V中邻接点的最短边
int addvnew[VNUM]; //标记某点是否加入Vnew
int adjecent[VNUM]={0}; //记录V中与Vnew最邻近的点void prim(int start)
{int sumweight=0;int i,j,k=0;for(i=1;i<VNUM;i++) //顶点是从1开始{lowcost[i]=edge[start][i];addvnew[i]=-1; //将所有点至于Vnew之外,V之内,这里只要对应的为-1,就表示在Vnew之外}addvnew[start]=0; //将起始点start加入Vnewadjecent[start]=start;for(i=1;i<VNUM-1;i++) {int min=MAX;int v=-1;for(j=1;j<VNUM;j++) {if(addvnew[j]!=-1&&lowcost[j]<min) //在Vnew之外寻找最短路径{min=lowcost[j];v=j;}}if(v!=-1){printf("%d %d %d\n",adjecent[v],v,lowcost[v]);addvnew[v]=0; //将v加Vnew中sumweight+=lowcost[v]; //计算路径长度之和for(j=1;j<VNUM;j++){if(addvnew[j]==-1&&edge[v][j]<lowcost[j]) {lowcost[j]=edge[v][j]; //此时v点加入Vnew 需要更新lowcostadjecent[j]=v; }}}}printf("the minmum weight is %d",sumweight);
}
五:如果大家觉得这篇博客有问题,欢迎提意见,博主会认真学习哒~
克鲁斯卡尔算法与普里姆算法详解相关推荐
- 【数据结构与算法】普里姆算法的介绍和修路问题程序实现
目录 1. 最小生成树的介绍 2. 普里姆算法的介绍 3. 修路问题的介绍 1. 最小生成树的介绍 最小生成树(Minimum Cost Spanning Tree),简称MST.给定一个带权的无向连 ...
- prim算法(普里姆算法)详解
prim算法(普里姆算法)详解 了解了什么是最小生成树后,本节为您讲解如何用普里姆(prim)算法查找连通网(带权的连通图)中的最小生成树. 普里姆算法查找最小生成树的过程,采用了贪心算法的思想.对于 ...
- 两种构造最小生成树的算法(普里姆算法,克鲁斯卡尔算法)
(一)普里姆算法 普里姆算法求最小生成树:从生成树中只有一个顶点开始,到定点全部进入生成数为止: 2.克鲁斯卡尔算法. 思想:将所有边按其权值从小到大排一遍,从小到大依次选取边,加入最小生成树中,若加 ...
- 克鲁斯卡尔算法 与 普里姆算法
克鲁斯卡尔算法 设G=(V,E)是具有n个顶点的连通网,T=(U,TE)是其最小生成树. 1.选取权值最小的边(Vi,Vj),若边(Vi,Vj)加入到TE后形成回路,则舍弃该边,否则将该边加入到TE中 ...
- 数据结构与算法|最小生成树算法(普里姆算法、克鲁斯卡尔算法)
最小生成树算法 C语言代码部分来自小甲鱼的<数据结构与算法> 文章目录 最小生成树算法 一.普里姆(Prim)算法 1.C语言代码 2.算法思路 二.克鲁斯卡尔(Kruskal)算法 1. ...
- 我所知道的十大常用算法之普里姆算法(最小生成树)
前言需求 今天我们学习的是普里姆算法,我们还是从一个场景里引入看看 有7个村庄(A, B, C, D, E, F, G) ,现在需要修路把7个村庄连通 1.各个村庄的距离用边线表示(权) ,比如 A ...
- 【算法】普里姆算法 Prim算法解决修路问题
文章目录 1. 概述 1.1 最小生成树 2.普里姆算法介绍 3.代码 3.1 案例1 1. 概述 视频:https://www.bilibili.com/video/BV1E4411H73v?p=1 ...
- 十大算法之普里姆算法
普里姆算法介绍 普利姆(Prim)算法求最小生成树,也就是在包含n个顶点的连通图中,找出只有(n-1)条边包含所有n个顶点的连通子图,也就是所谓的极小连通子图 普利姆的算法如下: 设G=(V,E)是连 ...
- 图论算法:普里姆算法(C++实现+图解)
文章目录 最小生成树 普里姆算法 实现过程 代码实现 最小生成树 什么是最小生成树? 对于如图所示的带权无向连通图来说:从图中任意顶点出发,进行dfs或者bfs便可以访问到图中的所有顶点,因此连通图中 ...
最新文章
- VSTO进行时––开发日志之二(VSTO Development diary II)
- iOS朋友圈,视频播放器、钓鱼小游戏、玻璃动画源码
- Java基础部分自测题(持续更新)
- 减小Delphi的Exe文件大小
- 互联网1分钟 |1227
- HDU 1233 还是畅通工程(最小生成树)
- 中国软件20年,向金山和中国软件英雄致敬!
- 数组的连续最大子段和
- Julia学习(1)——入门
- 外媒:英特尔未来10年可能投资950亿美元在欧洲新建8家芯片厂
- matlab平滑曲线_梯度下降法实现路径平滑
- linux新漏洞,「漏洞通告」Linux Kernel 信息泄漏权限提升漏洞(CVE-2020-8835)
- c++调用matlab
- html+css+javascript实现抖音超火罗盘时钟 (免费附源码)
- 面试官:如何理解TCP/IP协议?
- kodi文件管理smb服务器,KODI+NAS的常见技巧
- 还不会用 Python 提取 PDF 表格?三种类型数据,轻松转换成 Excel
- 【学习笔记】密码学入门(2) 单向散列函数,消息认证码,数字签名,证书
- NTU-RGBD骨架数据分析
- 数字图像处理 击中击不中变换