Prim算法和Kruskal算法都是解决最小生成树问题的经典算法。最小生成树是原图的最小连通子图,它包含原图的全部结点,且保持图连通的所有边代价和最小。一个连通图可能有多个最小生成树。
一、Prim算法
含义
Prim算法,也被称为普里姆算法,是图论中的一种算法,主要用于在加权连通图中搜索最小生成树。这意味着通过Prim算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。
主要思想:从某个顶点开始,不断选择与当前生成树相连的最小权值的边,将其对应的顶点加入到生成树中,直到所有顶点都加入到生成树中为止
算法步骤
(1)初始状态:U={u0},TE={}。其中,u0是顶点集合 V中的某一个顶点。
(2)在所有u属于U,U属于V-U的边(u,v)属于E中找一条权值最小的边(u0,v0),将这条边加进集合TE中,同时将此边的另一顶点v0并入U。
这一步骤的作用是在边集E里找一条两个顶点分别在集合 U和V-U中且权值最小的边,把这条边添加到边集 TE 中,并把这条边上不在U中的那个顶点加入到U中。
13
(3)如果U=V,则算法结束;否则重复步骤(2)。
图解
一、Kruskal算法
含义
Kruskal算法是一种用来查找最小生成树的算法,它使用的贪心准则是从剩下的边中选择不会产生环路且具有最小权值的边加入到生成树的边集中。
主要思想:先对图中的所有边按照权值进行从小到大的排序,然后从小到大依次选取边,若这条边连接的两个顶点不在同一个连通分量中,则将其加入生成树中,否则舍弃,直到生成树中包含所有顶点或者所有边都已遍历完
算法步骤
1、将图中的所有边按照权值从小到大进行排序。
2、初始化一个空的最小生成树。
3、依次遍历排序后的边,判断当前边的两个顶点是否在同一个连通分量中。如果不在同一个连通分量中,则将该边加入最小生成树中,并将这两个顶点合并到同一个连通分量中。如果已经在同一个连通分量中,则跳过该边,继续遍历下一条边。
4、重复步骤3,直到最小生成树中包含了所有的顶点,或者所有的边都已经遍历完毕。
图解
三、Prim算法和Kruskal算法的区别
1、时间复杂度
Prim算法的时间复杂度为O(V^2),其中V为顶点的个数;
而Kruskal算法的时间复杂度为O(ElogE),其中E为边的个数。在E远大于V的情况下,Kruskal算法更加高效。
2、实现方式
Prim算法可以使用邻接矩阵或邻接表来表示图,并且需要使用堆来维护当前生成树与剩余顶点之间的边的权重。
Kruskal算法可以使用并查集来判断加入的边是否形成回路。
3、适用场景
Prim算法适用于稠密图,即边的数量接近于顶点数量的平方;
而Kruskal算法适用于稀疏图,即边的数量接近于顶点数量的线性。