700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Prim(普利姆)算法c语言实现

Prim(普利姆)算法c语言实现

时间:2023-10-17 02:03:11

相关推荐

Prim(普利姆)算法c语言实现

//代码缩进有点难受,改了一下

关于最小生成树的算法,那么肯定要提到大名鼎鼎的prim和kruskal算法, 这两种算法思想大同小异。对于算法的学习,我的经验是搞懂思想,分模块去记忆,而不是去背代码,虽然短时间内,背代码确实可以较快的出程序,但是当算法非常多时,很容易混乱。

废话不多说,先说思想。

前提:边有权,连通图,采用邻接矩阵存储,因为我贪方便,所以无穷大就是未被赋值的一个负的随机值

Prim算法:( 三步走)

核心:

理解并掌握lowcost数组的意义(存放树的邻接边,如果有两条边指向同一个结点,那么存储较小的那一个)

1.(初始化)

初始化lowcost数组,将lowcost先初始化为v0结点的边的权值,此题为

代码为:

for (i = 0; i < graph->num; i++) {//初始化lowcost,treelowcost[i] = graph->vortex[0][i];tree[i] = 0;}

tree用于存放最小生成树,也先置0;

2.(寻找最小值)

现在我们已经知道了v0的周围一圈,那么我们就在这一圈里面找到最小的一条边,此题为v0到v2的边并把v2标记下来。然后把k收录进树,我们用lowcost=0来标记这个结点以及被收录进了树。

代码为:

for (i = 0; i < graph->num; i++) {//寻找lowcost最小值if (lowcost[i] < min && lowcost[i]>0){min = lowcost[i];k = i;}}lowcost[k] = 0;

3.(更新lowcost)

既然v2已经被收录进了树,v2也是有邻接点的,那么这棵树的邻接点也必须要改变(红色表示这棵树的邻接边,蓝色表示这棵树)

我们会发现,有两条边指向了同一个点,该如何取舍呢?

对的,找短的那条

然后lowcost为

代码为:

for (i = 1; i < graph->num; i ++) {//更新lowcost[]的值并将i收进树if ((lowcost[i]<0||lowcost[i] > graph->vortex[k][i])&&graph->vortex[k][i]>0) {//和k有边连着.两种情况,1.比原来的权小,2.原来的权无lowcost[i] = graph->vortex[k][i];tree[i] = k;}}

完整代码给你们了:

void Prim(G* graph) {int lowcost[MAX], i, j, min, k;int tree[MAX];for (i = 0; i < graph->num; i++) {//初始化lowcost,treelowcost[i] = graph->vortex[0][i];tree[i] = 0;}for (j = 1; j < graph->num; j++) {//仅仅用于标记循环次数min = 32767;for (i = 0; i < graph->num; i++) {//寻找lowcost最小值if (lowcost[i] < min && lowcost[i]>0){min = lowcost[i];k = i;}}lowcost[k] = 0;for (i = 1; i < graph->num; i++) {//更新lowcost[]的值并将i收进树if ((lowcost[i]<0 || lowcost[i] > graph->vortex[k][i]) && graph->vortex[k][i] > 0) {//和k有边连着.两种情况,1.比原来的权小,2.原来的权为∞lowcost[i] = graph->vortex[k][i];tree[i] = k;}}}for (i = 0; i < graph->num; i++) {printf("%d ", tree[i]);}}}

到这里就完结了,win10的画图真不好用,画了半天还是好丑哦。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。