关于Prim算法和Kruskal算法

      Prim算法和Kruskal算法都是描述连通图的最小生成树(最小权重生成树),也就是极小连通子图.( 就是在连接原图所有节点的情况下,使边的权值相加最小的通路)

Prim算法

      Prim算法的思路是随机从图上一个节点出发,选择与该节点连接的边中权值最小的边,再从该节点和与之相连的另一节点出发选择权值最小的边,但是新选择的节点和边不能与原有节点,边构成圈,以此类推,直至连接所有节点.

    如下图,在选择了A,C,F,D后有三条权值为5的边,为什么选择BC而不选择其他的呢?因为如果选择AD,ACFD构成圈,选择CD,则CDF构成圈, 因为是最小生成树,所以除树根外,树的各节点都只有一个父亲节点,树是不会构成类似圈的形状( 术语忘了,就是描述的样子)

 算法代码构成思路:

     图的结构我使用的是邻接表

    1.使用一个全局数组visited[] , 如果最小权值边确认下来, 边两边的节点都被访问过了,以节点为横坐标的visited数组 等于 1,在寻找新的权值最小边的时候,边的另一节点不能在visited数组上,即visited数组不能为1.

    2.寻找新的权值最小边时, 出发节点要从visited数组为1的节点处,遍历与他们相连的所有边,寻找权值最小的边.( 当然我这种做法可能会使在寻找第二处等以后的边时,前面的最小权值边被重复遍历,又因visited数组为1而遍历后面)

Kruskal算法

   Kruskal算法的思路是在图中寻找权值最小的边,然后排除该边后,在剩余边中寻找权值最小的边,,但是新选择的节点和边不能与原有节点,边构成圈以此类推直至连接所有节点. 

   要避免的情况其实和Prim算法差不多

算法代码构成思路:

     1.遍历邻接表,将所有边的节点,权值输入到一个结构体数组中,数组根据权值升序排序

     2.一个source函数, fat数组  以节点为横坐标的fat数组的值为它本身( 横坐标值 ).

     3.如果刚来时 头两个节点相连,那么其中一个节点的fat数组的值为另一节点.一个节点的源头为另一节点

     4. 后面的俩个节点,其中一个节点的源头的节点的fat数组的值为另一节点源头

Kruskal算法可以参考https://blog.csdn.net/qq_41754350/article/details/81460643

 

两个算法的证明

简单证明prim算法

反证法:如果prim生成的不是最小生成树

1).设prim生成的树为G0

2).如果存在Gmin使得cost(Gmin)<cost(G0)   则在Gmin中存在<u,v>不属于G0

3).将<u,v>增加G0中可得一个环。且<u,v>不是该环的最长边(这是由于<u,v>∈Gmin)

4).这与prim每次生成最短边矛盾

5).故如果不成立,命题得证.

简单证明Kruskal算法

对图的顶点数n做归纳,证明Kruskal算法对随意n阶图适用。

归纳基础:

n=1。显然能够找到最小生成树。

归纳过程:

如果Kruskal算法对n≤k阶图适用,那么,在k+1阶图G中。我们把最短边的两个端点a和b做一个合并操作,即把u与v合为一个点v'。把原来接在u和v的边都接到v'上去。这样就能够得到一个k阶图G'(u,v的合并是k+1少一条边),G'最小生成树T'能够用Kruskal算法得到。

我们证明T'+{<u,v>}是G的最小生成树。

用反证法,如果T'+{<u,v>}不是最小生成树,最小生成树是T。即W(T)<W(T'+{<u,v>})。

显然T应该包括<u,v>,否则,能够用<u,v>增加到T中,形成一个环,删除环上原有的随意一条边,形成一棵更小权值的生成树。而T-{<u,v>}。是G'的生成树。所以W(T-{<u,v>})<=W(T')。也就是W(T)<=W(T')+W(<u,v>)=W(T'+{<u,v>}),产生了矛盾。于是如果不成立。T'+{<u,v>}是G的最小生成树。Kruskal算法对k+1阶图也适用。

由数学归纳法,Kruskal算法得证。

证明引用自https://www.cnblogs.com/zhchoutai/p/8687614.html

算法过程图图片引用自https://blog.csdn.net/a2392008643/article/details/81781766

 

如有错误或者不当,请多担当

我的代码:https://github.com/zhangweifeng66/algorithms/blob/master/Kruska

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值