最小生成树-普利姆算法(加点法)及其实现【C/C++】


前言

一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。
这里主要讲解普利姆算法的思路及其实现过程。


一、最小生成树是什么?

在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集且为无循环图,使得联通所有结点的的 w(T) 最小,则此 T 为 G 的最小生成树。

二、普利姆算法的思想

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
3).重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。

三、耿国华老师的具体实现步骤

为了实现这个算法设置一个辅助数组closedge[],记录从U到V-U具有最小代价的边。
closedge[v]包括两个域,adjvex和lowcost,其中lowcost记录最小边的权值,adjvex记录最小边在U中的顶点。

struct {
	int adjvex;
	int lowcost;
}closedge[MAX];

3.1 算法思想

1.首先将初始v0加入U中,并对其余的每个顶点i,将closedge[i]均初始化为i到v0的边的信息。
2.由于v0自己不用完成搜索,因此再循环n-1次,做如下处理。
3.从各组最小边closedge[]中选择最小的最小边closedge[v]。
4.将v加入U中,这里的加入就是closedge[v].lowcost=0;
5.更新剩余的每个最小边信息closedge[i]
6.对于以i为中心的那组边,如果新边的权值比closedge[i].lowcost小,则将closedge[i].lowcost更新为新边的权值。

3.2 个人在实现时遇到的问题

耿老师将v纳入U后将closedge[v].lowcost=0,但是在新边搜索时应当把closedge[i].lowcost=0的边踢出去,否则会是死循环。

3.3 具体代码

#define INFINITY 65535
struct {
	int adjvex;
	int lowcost;
}closedge[MAX];//辅助数组

void PrimMiniSpanTree(AdjMatrix g, int v0) {
	closedge[v0].lowcost = 0;
	for (int i = 0; i < g.vexnum; i++) {
		if (i != v0) {
			closedge[i].adjvex = v0;//初始将所有顶点的邻点设为v0
			closedge[i].lowcost = g.arcs[v0][i].adj;
		}
	}
	for (int i = 0; i < g.vexnum - 1; i++) {//v0已经完成任务,因此循环n-1次
		int min = INFINITY;//保存最小边的权值
		int index = 0;//保存最小边的下标
		for (int j = 0; j < g.vexnum; j++) {
			if (closedge[j].lowcost != 0 && closedge[j].lowcost < min) {
				min = closedge[j].lowcost;
				index = j;
			}
		}
		printf("(%c,%c) ", g.vertex[closedge[index].adjvex], g.vertex[index]);//输出最小边的信息
		closedge[index].lowcost = 0;//closedge[].lowcost=0表示该顶点已经完成任务,下一次以该顶点的邻边进行搜寻。
		for (int j = 0; j < g.vexnum; j++) {
			if (closedge[j].lowcost != 0 && g.arcs[index][j].adj < closedge[j].lowcost) {
				closedge[j].lowcost = g.arcs[index][j].adj;
				closedge[j].adjvex = index;
			}
		}
	}
}

3.4 测试结果

这里采用的图及其权值如下图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里以A为顶点,显然是对滴。
再以G为顶点
在这里插入图片描述
显然也是对滴。


总结

把握思想,就能实现!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠菠萝宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值