数据结构与算法-100 Days of learning-day5

用Kruskal算法构建最小生成树

1)算法描述(将森林合并成树)
对于一个无向连通图G,设其最小生成树为T。最小生成树在初始状态下是由|V|个顶点构成,而且各顶点之间无任何边(每个顶点都是一棵树,所以说初始状态就是一片森林)。此时T中的每个顶点都是一个只有一个顶点的连通分量。
那么,将森林合并成树用到的就是贪心算法中的Kruskal算法。它每次只选取权重最小的边,然后将其收录进去,同时在这个过程中要一直满足不能生成回路。那么什么时候会出现回路?当待选取边相关联的两个顶点属于同一个连通分量时,选取该边就会出现一条回路。所以如果两个顶点分别属于不同的连通分量,那么就可以收录这条将这两个顶点相连接的边。这样也就把两个不同的连通分量变成一个连通分量。这样的操作一直进行到树的边数达到|V|-1。每次都以最小的代价将两棵不同的树连接成一棵树,最终显然形成了最小生成树。
2)具体例子
在这里插入图片描述
图 14
此处以边为集合的变化来描述最小生成树的生长过程。初始状态,当前状态是7个顶点形成的“森林”。最小生成树T={∅},也就是说此时并没有收录边。接着,如图14(a)所示,将权重为1的边收录其中(两条边的收录顺序不分前后)V1,V4分别属于不同的连通分量;V6,V7分别属于不同的连通分量。所以不可能有回路出现。此时T={{V1,V4,1},{V6,V7,1}},当前森林变成了|V|-2颗树形成的森林。
然后,如图14(b)所示,分别将权重为2的两条边收录到集合里,同理这过程中无回路产生,此时T={{V1,V4,1},{V6,V7,1},{V3,V4,2},{V1,V2,2}}。
接着,如图14(c)所示,本来应该选取权重为3的边{V2,V4,3},但V2,V4属于同一棵树,也就是同一个连通分量。那么将这两点连在一起必定会出现回路。同理对于权重为4的边{V1,V3,4}也是如此。所以最后将符合要求的边{V4,V7,4}收录到集合中,此时T={{V1,V4,1},{V6,V7,1},{V3,V4,2},{V1,V2,2},{V4,V7,4}},当前森林变成了|V|-5颗树形成的森林。
接着,如图14(d)所示,将权重为6的边{V5,V7,6}收录到树集合T中,此时所收集到的边数达到了|V|-1。同时将所有顶点连接成为了一颗最小生成树。
3)算法伪码描述:
在这里插入图片描述
首先,该算法要传入图结构。在刚开始最小生成树的集合中无任何边,为空集。接着进入while循环语句,从边集合E中取一条权重最小的边E(v,w)(将每条边都遍历一遍的方法不如用最小堆存储),并将其从边集合中删除。然后看取出的边E(v,w)在MST中是否构成回路(这里可以采用并查集。比如原本两个独立的顶点(相当于独立集合),若收录的边将两棵树合并为一棵树(此时一个顶点就可以看做一棵树),就相当于将两个独立集合并成一个集合)。如果V,M两个顶点属于不同的树,不会形成回路,则将该边放在最小生成树MST集合当中。否则,不将其放在MST中,直接无视。在MST中的边数未达到|V|-1或者边集合E中仍然有边没有被遍历时,该循环持续进行。所以该循环停止的时候,E中无边而MST边数未达到|V|-1,这个时候所生成的结构就不叫生成树。
4)算法时间复杂度
While语句循环的次数最多进行|V|次。每次在内部调用最小堆的查找操作,其时间复杂度为O( log|V| )。接下来在看E(v,w)在MST中是否构成回路的过程中用到了并查集,也就是并运算(用union函数),查(Find函数),时间复杂度同样为树的高度O( log|V| )(树.docx中含有详细描述)。所以总体时间复杂度为O( |E|·log|V| )。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值