最小生成树->Prim算法和Kruskal算法

背景:在学习图的知识时,最小生成树是一个最普遍的概念。它在日常生活中的应用很普遍,比如:有A、B、C、D、E五个城市,现在想在五个城市之间建设通信线路连通,每两个城市之间修建线路的费用不同,我们当然想用最小的代价将五个城市通信连接起来,这时,如何获取最小代价的方案,也就是如何找到最小生成树就显得尤为重要。

如何寻找最小生成树,目前常用的有Prim(普里姆)算法和Kruskal(克鲁斯卡尔)算法,接下来我们一个一个详细地介绍其原理。

为了方便理解,我们用一个图来直观地展示着两个算法。下图中A、B、C、D、E分别表示五个城市,每条边上的数字表示两个城市之间的修建通信线路的代价。设原图中顶点集合为U,关系集合为V;生成树中点的集合为u,关系集合为v。

                                                                

Prim算法:先选取一个顶点如A作为起点,将该点加入到集合u中,之后从和u中所有点相关联,且终点在集合U-u中的所有边中找出一条权值最小的边。将该边的存入v中,同时将该边的终点存入到u。重复以上步骤直至u中包含U中所有点。图解如下所示。

 

下面我们再用文字来记录一下Prim算法寻找最小生成树的步骤:

选出顶点A,将A存入到集合u中。

此时u中只有顶点A,和A相关联且终点在U-u中的边有A->B,A->C,A->E,这三条边中权值最小的为A->B,将关系A->B加入到集合v,同时将点B加入到集合u。

此时u中有顶点A,B,和u中点相关联且终点在U-u中的边有A->C,A->E,B->C,这三条边中权值最小的为A->C,将关系->C加入到集合v,同时将点C加入到集合u。

重复以上步骤,直至u中包含所有点。

Kruskal算法:每次从集合V中选出一条权值最小,且加入到v中后不会形成环的边,将该边从V中删除,并加入到v中,同时将该边的起点和终点加入到u中,若u中已有该顶点则忽略。重复上述步骤直至u中含有所有的点。图解如下所示:

下面我们用文字来记录一下Kruskal寻找最小生成树的步骤:

从集合V中选出一条权值最小且加入到v中后不会形成环的边,该边为A->B,将该边加入到v中,并从V中删除,同时将A,B两个点加入到u中。

从集合V 中再选出一条权值最小且加入到v中后不会形成环的边,该边为C->E,将该边加入到v中,并从V中删除,同时将C,E两个点加入到u中。

从集合V 中再选出一条权值最小且加入到v中后不会形成环的边,该边为A->C,将该边加入到v中,并从V中删除,同时将A,C两个点加入到u中。由于A,C已经在u中,忽略这两点。

从集合V 中再选出一条权值最小且加入到v中后不会形成环的边,该边为C->D,将该边加入到v中,并从V中删除,同时将C,D两个点加入到u中。由于C已经在u中,忽略C点。此时u中已经包含有所有的点,算法结束。