算法(5)-最小生成树(Prim算法和Kruskal算法)

定义

最小生成树是一副连通加权无向图中一棵权值最小的生成树,最小生成树其实是最小权重生成树的简称,

例如常见的修建公路之类的问题,用到的就是最小生成树算法,常见的最小生成树算法有Prim算法和Kruskal算法

普里姆算法(Prim算法)

从单一顶点开始,普里姆算法按照以下步骤逐步扩大树中所含顶点的数目,直到遍及连通图的所有顶点。

  1. 输入:一个加权连通图,其中顶点集合为V,边集合为E;
  2. 初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {};
  3. 重复下列操作,直到Vnew = V:
    3.1. 在集合E中选取权值最小的边(u, v),其中u为集合Vnew中的元素,而v则是V中没有加入Vnew的顶点(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
    3.2. 将v加入集合Vnew中,将(u, v)加入集合Enew中;
  4. 输出:使用集合Vnew和Enew来描述所得到的最小生成树

例如计算下图的最小生成树


伪代码如下:

  1. 从A点开始,获取与A点相连的权重最小的边,即AD,然后将A点和D点加入集合{A,D}
  2. 将集合{A,D}当做一个整体,获取与它相连权重最小的边,此时AB和DF权重都是最小,所以将BF加入集合{A,B,D,F}
  3. 将集合{A,B,D,F}当做一个整体,获取权重最小的边,此时BC和FE权重最小为8,然后将CE加入集合{A,B,C,D,E,F}
  4. 最后将集合{A,B,C,D,E,F}看成一个整体,获取权重最小的边,此时EG最小,为9,这时最小生成树就得到了


克鲁斯克尔算法(Kruskal算法)

Kruskal算法大致步骤

  1. 将原图中所有的边按权值从小到大排序
  2. 从权值最小的边开始,如果这条边连接的两个节点于图G中不在同一个连通分量中,则添加这条边到图G中
  3. 重复2,直至图G中所有的节点都在同一个连通分量中
    还是刚才的那个例子获取最小生成树


伪代码如下

  1. 将原图中所有的边按权值从小到大排序
  2. 从权值最小的开始,添加边AD到集合{AD}
  3. 重复步骤2,依次添加CE,DF,AB,BE到集合{AD,CE,DF,AB,BE}
  4. 重复步骤2,需要注意的是,此时集合中已经有AD,AB两条边,也是就它们已经在一个连通分量中了,所有注意不要添加BD这条边,同理的还有BE和CE边的存在,就不添加BC边,按照这样的逻辑重复步骤2,即可获得结果集合{AD,CE,DF,AB,BE,EG}


你可能感兴趣的:(算法(5)-最小生成树(Prim算法和Kruskal算法))