最小生成树算法

本文详细介绍了最小生成树的概念,并重点解析了Kruskal和Prim两种贪心算法,包括它们的基本思想、时间复杂度及适用场景。通过具体的例子展示了算法的实现过程,帮助读者深入理解最小生成树的构建方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最小生成树算法是给定一个无向图,及其顶点和边的权值,在确保所有顶点都是连通即整个无向图的连通分量为1的情况下使得所有边的权值之和最小的算法,这个时候其实图已经退化为树了。

下面介绍一下最小生成树的两种算法:kruskal算法和prim算法。它们都属于贪心算法,只是贪心的理解角度不同导致的两种算法。对于最小生成树,最简单的最优度量准则是:选择迄今为止已入选S中边的代价之和增量最小的边。(其中S代表已经入选最小生成树集合的边)

一)kruskal算法:

贪心准则:按边的权值非降序考察E中的边,从中选择一条代价最小的边。这种做法使得算法在构造生成树的过程中,边集S代表的子图不一定是连通的,而且为了确保最终得到一棵生成树,每选择一条边时都需要判断SUe是否包含回路。时间复杂度为0(eloge),其中e为图中边的个数,需要结合并查集解决。适合在稀疏图中。

二)prime算法:

贪心准则为:在保证S所代表的子图是一棵树的前提下选择一条最小代价边e=(u,v)。由于其选边方式已经确保S所代表的子图自然是一棵树。故无需判断边集SUe是否包含回路。

时间复杂度为O(n*n),适合在n比较小的情况下。

 

两种算法的实现分别如下:

prim算法的思想是加点法。即开始时任意从图中选择一个点,作为U集合,其余点为S-U集合,其中S为原图中的顶点集合,求U集合中顶点到S-U集合中顶点的最小距离,这个最小距离即为最小生成树的组成边,然后将对应最小距离的S-U集合的顶点放入U集合,然后重复执行上述操作,直至U集合=S集合。

而kruskal算法则是加边法,即将图的边先从小到大排序,然后结合并查集依次加边,注意不能形成环,这也是并查集的作用,每次成功加入的边即为最小生成树的组成边。下面是代码:

//图的邻接矩阵表示法
#include <stdio.h>
#include <stdlib.h>
#define Max 100
#define Inf 0x1111
typedef char type;
typedef struct Grap{
	type data[Max];
	int value[Max][Max];
	int n,m;
}Grap,*pgrap;
struct Adjtrim{
     int index;
     int dis;
}trim[Max];	 
int Located(pgrap g,char ch){
	for(int i=0;i<g->n;i++)
		if(g->data[i]==ch)
			return i;
}
void Creat_grap(pgrap g){
	printf("输入图的顶点数和边数:\n");
	scanf("%d%d",&g->n,&g->m);
	//printf("ksgfdkj\n");
	getchar();
	printf
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值