Prim算法与Kruskal算法都是用来求连通网的最小生成树问题的方法。首先让我们来创设一个情景:
- 某营业厅接到一个单子,要求给一所学校新建校区安装宽带
- 该学校教学楼、宿舍分别用(A, B, C, D, E, F, G)来代表
- 问:如何修路保证各个站点都能连通,并且线路最短
Prim算法
1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
3).重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。
以上是来自百度百科对Prim的描述,那他到底是怎么执行的呢,我们看看流程图
-
首先我们确定一根节点,然后从此节点出发,利用贪心算法寻找权值最小的边。逐步扩大所含顶点的数目,直到遍及连通图的所有顶点。
-
这里我们选取A点为起始点,那么Prim的流程就如下图所示
-
最后黄色所连成的树就是Prim算法的最小生成树
Kruskal算法
百度百科中对Kruskal是这样描述的:
克鲁斯卡尔算法是求连通网的最小生成树的另一种方法。与普里姆算法不同,它的时间复杂度为O(eloge)(e为网中的边数),所以,适合于求边稀疏的网的最小生成树
- 其基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),概述图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点分别在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边而选择下一条代价最小的边。依此类推,直至T中所有顶点构成一个连通分量为止
- 流程如下
Prim算法与Kruskal算法比较
Prim算法的核心步骤是增加点,针对点考察边,与网中的边数无关,因此适合求解稠密图最小生成树。Kruskal算法是针对一条边的扫描和排序,借助“堆”存放。
算法名 | 普利姆算法 | 克鲁斯卡尔算法 |
---|---|---|
基本思想 | 以顶点为对象 | 以边为对象 |
时间复杂度 | O(n²) | O(eloge) |
适应范围 | 稠密图 | 稀疏图 |
Prim算法实现
pass
Kruskal算法实现
pass