1 问题描述
何为Kruskal算法?
该算法功能:求取加权连通图的最小生成树。假设加权连通图有n个顶点,那么其最小生成树有且仅有n - 1条边。
该算法核心思想:从给定加权连通图中,选择当前未被选择的,不能形成回路且权值最小的边,加入到当前正在构造的最小生成树中。
2 解决方案
2.1 构造最小生成树示例
下面请看一个具体示例:
给定一个加权连通图,其包含5个顶点,分别为:1,2,3,4,5。包含7条边,按照从小到大排序依次为:
1-2,5
2-3,5
3-5,6
2-4,12
4-5,12
2-5,15
3-4,17
那么可知,使用kruskal算法构造该加权连通图的最小生成树,则需要选择出这7条边中满足定义的4条边。
(1)原始图
(2)添加第1条边
此时未选中任何一条边,那么直接选择7条边中最小的一条边,2-3,5。(PS:当权值最小的边有多个时,只要满足定义,可以随意选择一条边即可。例如,此处也可以选择1-2,5)
(2)添加第2条边
此时,从剩余的6条边中选择最小权值的边,可以轻易知道为1-2,5。加入此边后,检查此时的正在构造的最小生成树,没有回路,符合定义,即可以确认加入。
(3)添加第3条边
此时,从剩余的5条边中选择最小权值且不会生成环的边,轻易可知,3-5,6符合要求。
(4)添加第4条边(PS:此时也是最小生成树的最后一条边)
从剩余的4条边中选择最小权值且不会生成回环的边,发现2-4,12、4-5,12均符合要求,此时,任意选择其中一条边即可。这里,我选择的是4-5,12。
(5)最小生成树以及构造完毕,结束构造。
2.2 伪码及时间效率分析
该算法在开始的时候,会将给定连通图所有边的权值进行从小到大排列。然后,从一个空子图开始,它会扫描这个这个有序列表,并试图把列表中的下一条边加入到当前正在构造的子图(或者说是最小生成树)中。当前,这种添加不能形成一个回路,如果产生了回路,则把这条边跳过。
Kruskal(G) {
//构造最小生成树的Kruskal算法
//输入:加权连通图G = <V, E>,其中V为顶点数,E为具体边集合
//其中E中边已经经过处理,按照权值从小到大排列
//输出:Et,组成G的最小生成树的边的集合
Et = 空集;
int coun