最小生成树--普利姆(Prim)算法

最小生成树

1. 为什么要构造最小生成树?什么是最小生成树?
假设要在n个城市之间建立通信联络网,则连通n个城市只需要n-1条线路。这时,自然会考虑这样一个问题,如何在最节省经费的前提下建立这个通信网。
在每两个城市之间都可以设置一条线路,相应地都要付出一定的经济代价。N个城市之间,最多可以设置n(n-1)/2条线路,那么,如何在这些可能的线路中选择n-1条,以使总的耗费最少呢?
在n个城市之间架设n-1条线路,使得这n个城市是连通的,这就是一个构造生成树的过程.在这n(n-1)/2中可能的方案中,选取总的耗费最小那一颗生成树,这就是最小生成树。
2.  如何构造最小生成树?
构造最小生成树的算法有普利姆(Prim)算法和克鲁斯卡(Kruskal)算法。这两个算法都是利用了最小生成树的性质:假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集。若(u,v)是一条具有最小权值的边,其中u属于U,v属于V-U,则必存在一颗包含边(u,v)的最小生成树。
本文将实现普利姆(Prim)算法。那么首先来看看Prim算法实现的基本原理:假设N=(V,{E})是一个连通网,TE是N上最小生成树中边的集合。算法从U={u0}(u0 属于V),TE={}开始,重复执行下述操作:在所有的u属于U,v属于V-U中的边(u,v) E中找一条代价最小的边(u0,v0)并入集合TE,同时v0并入U,直至U=V为止。此时TE中必有n-1条边,则N=(V,{TE})为N的最小生成树。
思路决定出路。上面啰嗦这么多,只是为了从本质上认识最小生成树,以及最小生成树构造的原理。思路理清楚了,实现只不过是个过程而已,不会有迈步过去的砍。下面我们再更详细地描述下Prim算法。功夫不会负有心人的,磨刀也不会无砍柴工,相信我!思路理清楚了,程序写起来很快滴!^0^
为了实现这个算法需附设一个辅助数组closedge,以记录从U到V-U具有最小代价的边。对每个顶点vi V-U,在辅助数组中存在一个相应分量closedge[i-1],它包括两个域:vex和lowcost。closedge[i-1].lowcost=Min{cost(u,vi)|u U}。vex域存储该边依附在U中的顶点。


具体算法描述:
1. 初始化closedge数组,用起始顶点到其它各结点权值初始化该数组。
2. 找出closegde数组中最小的权值的那个数组元素closedge[k]并将k并入到U中。这个并入的过程用将closegde[k].lowcost修改为0来标记。(V-U中各顶点到U中各顶点的权值最小的那个顶点。)
3. 将结点k到其它结点j(1<=j<=vetexnum)的权值arc[k][j]与数组closedge[j]. lowcost进行比较。若arc[k][j]<closedge[j]. lowcost,则closedge[j].lowcost = arc[k][j]。这样closegde数组中存储的就是V-U中各顶点到U中各顶点的最小值。(U中增加元素了,修改closedge)。
4. 若U==V则退出,最小生成树生成。否则,返回步骤2。

记住:closegde[j].lowcost中存储的是V-U中结点j到U中各结点的最小权值。

下面是算法实现:(思路清白了,程序实现20分钟就搞定^0^)

 

这只是一个表述Prim算法的类。若要是该算法为你构造最小生成树,那还需写一个驱动程序。注意该算法中输入的图是以邻接矩阵的数据结构进行存储的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值