最小生成树

    最小生成树:n个顶点,用n条边构造连通网最小权值和的生成树。

 

1.普里姆(prim)算法:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pel5L2c5pyI5oGv,size_20,color_FFFFFF,t_70,g_se,x_16

 算法流程:

第一步:创建两个一维数组lowcost和adjvex,长度都为顶点个数,此图中长度为9。

 

第二步:adjvex[0]=0,表示从顶点V0开始,

lowcost[0]=0,表示V0被纳入最小生成树了,之后凡是lowcost数组中被设为0的下标对应的顶点都表示被纳入最小生成树中。

 

第三步:把上图的邻接矩阵的第一行的数据赋给数组lowcost,∞用65535表示,则此时lowcost值为:[0,10,65535,65535,65535,11,

65535,65535,65535],adjvex则全部为0。

 

第四步:定义变量min存储lowcost数组的最小值,已经是生成树的顶点不参与最小值的查找,并定义变量k存储该最小值的下标。则min=10,k=1。

 

第五步:打印(adjvex[k],k),也就是(0,1),表示V0到V1为最小生成树的第一条边。

 

第六步:将lowcost[k]=0,表示把顶点V1纳入最小生成树中。此时lowcost数组的值为:[0,0,65535,65535,65535,11,65535,65535,

65535]。

 

第七步:查找邻接矩阵第k行的各个权值与lowcost数组的对应值比较,从1开始,若更小则更改lowcost的对应值,并将k值存入adjvex数组中。因为k=1,所以第1行为:[0,18,65535,65535,65535,16,65535,12]

已纳入最小生成树的顶点的值不参与比较

所以更改后的lowcost值为:[0,0,18,65535,65535,11,16,65535,12]

更改后的adjvex值为:

[0,0,1,0,0,0,1,0,1]

 

第八步:此时min=11,k=5,打印(0,5),生成最小生成树的第二条边,V0到V5。

 

第九步:重复上述操作,直到最小生成树的8条边都找出来。

 

最小生成树的边有:(V0,V1),(V0,V5),(V1,V8),(V8,V2),(V1,V6),(V6,V7),(V7,V4),(V7,V3)

 

理解普利姆算法:

设两个顶点的集合,一个为空U,一个包含图的所有顶点V。然后从V集合取出一个顶点放到空集合U里,然后找出该顶点的最小权值边,并把该边的另一个顶点从V集合中取出放到U集合,继续找出U集合中通往该集合之外的顶点的最小权值边,并把该边的另一个顶点从V集合中取出放到U集合,循环这个过程,直到U集合包含图的全部顶点。

 

 

克鲁斯卡尔算法:

需要用到图的边集数组,并对它们的权值按从小到大排序:

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pel5L2c5pyI5oGv,size_20,color_FFFFFF,t_70,g_se,x_16 

 算法流程:

第一步:声明一个数组parent,并把它所用元素初始化为0,edges数组已存在边集数组中。

 

第二步:循环每一条边,调用Fine函数为变量n,m赋值。Fine函数要求传入parent数组和一个int值f,循环直到parent[f]不大于0为止,否则执行f=parent[f],最后返回f。(返回的是该顶点在最小生成树中与它连通的"最大顶点"(终点))

 

第三步:n=Fine函数传入parent数组和边的begin值,第一条边传入parent数组和4,因为parent[4]=0,所以n=4。

 

第四步:m=Fine函数传入parent数组和边的end值,第一条边传入parent数组和7,因为parent[7]=0,所以m=7。

 

第五步:如果n!=m,此边没有与现有生成树形成环,执行parent[n]=m,并打印该边和权值。因此parent[4]=7,打印(4,7)7。此时parent数组为:[0,0,0,0,7,0,0,0,0]。

 

第六步:循环第二条边,n=2,m=8,parent[2]=8,打印(2,8)8,此时parent数组为:[0,0,8,0,7,0,0,0,0]。

 

第七步:循环第三条边,n=0,m=1,parent[0]=1,打印(0,1)10,此时parent数组为:[1,0,8,0,7,0,0,0,0]。

 

第八步:循环第四条边,n=1,m=5,parent[1]=5,打印(0,5)11,此时parent数组为:[1,5,8,0,7,0,0,0,0]。

 

循环结束后的parent数组为:

[1,5,8,7,7,8,7,0,6]。

 

 

理解克鲁斯卡尔算法:

令最小生成树的初始状态只有n个顶点而无边的非连通图,图中每个顶点自成一个连通分量。然后在边集数组中选权值最小的边加入最小生成树中,并且加入后不形成回路,否则选下一条最小权值的边,以此类推,直到生成最小生成树。(通过Fine函数记录顶点的终点,加入边时,判断该边的两个顶点的终点是否重合,重合则构成回路,否则记录其顶点的终点)

 

 

总结:克鲁斯卡尔算法适合用于边少的稀疏图,而普利姆算法适用于边多的稠密图。

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值