Ef90e8787acc0dfc88210e621b1011e0
数据结构与算法——最小生成树

1 引言

  在之前的文章中已经详细介绍了图的一些基础操作。而在实际生活中的许多问题都是通过转化为图的这类数据结构来求解的,这就涉及到了许多图的算法研究。
  例如:在n个城市之间铺设光缆,以保证这n个城市中的任意两个城市之间都可以通信。由于铺设光缆的价格很高,且各个城市之间的距离不同,这就使得在各个城市之间铺设光缆的价格不同。那么如何选择铺设线路的方案,才能使费用最低呢?这就涉及到我们今天要研究的图的最小生成树问题。

2 重要概念

在学习最小生成树之前需要先明确几个重要概念。
  连通图:在无向图中,若任意两个顶点与都有路径相通,则称该无向图为连通图。
  强连通图:在有向图中,若任意两个顶点与都有路径相通,则称该有向图为强连通图。
  连通网:在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接连个顶点的代价,称这种连通图叫做连通网。
  生成树:一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。
  最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。

3 普里姆算法—Prim算法

  普里姆算法(Prim算法)是加权连通图里生成最小生成树的一种算法。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克发现;并在1957年由美国计算机科学家罗伯特·普里姆独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。

3.1 算法流程

  (1)对于一个加权连通图,其顶点集合为V,边集合为E。从集合V中任选一个顶点作为初始顶点,将该顶点标为已处理;
  (2)已处理的所有顶点可以看成是一个集合U,计算所有与集合U中相邻接的顶点的距离,选择距离最短的顶点,将其标记为已处理,并记录最短距离的边;
  (3)不断计算已处理的顶点集合U和未处理的顶点的距离,每次选出距离最短的顶点标为已处理,同时记录最短距离的边,直至所有顶点都处理完。
  (4)最终,所有记录的最短距离的边构成的树,即是最小生成树。

3.2 算法图解

例如:图3.2.1所示的带权无向图,采用Prim算法构建最小生成树过程如下。
图3.2.1

图3.2.1

(1)首先,选取顶点A作为起始点,标记A,并将顶点A添加至集合U中。

(2)集合U中只有一个顶点A,与A邻接的顶点有B和C,B、C距A的距离分别为6、3。选择距离最短的边(A,C),将C标记,并将C添加至集合U中。

(3)集合U中顶点为A和C。与顶点A邻接的有B、C,对应距离为6、3。与C邻接的顶点有B、F、E,对应的距离为4、7、8。由于顶点A、C均被标记,故不能选择距离为3的路径。此时应选择距离最短边(C,B)。标记B、并将B添加至集合U中。

(4)集合U新加入顶点B。与顶点B邻接顶点有A、C、D、F。A、C已经在集合内,不能再被选取。顶点B到顶点D、F的距离分别为2、3。顶点C到顶点E、F距离分别为7、8。因此选择距离最短边(B,D),将D标记,并将D添加至集合U中。

(5)集合U中顶点有A、B、C、D。顶点A无可选顶点。顶点B可选顶点有F,距离为3。顶点C可选顶点有E、F,对应距离分别为8、7。顶点D可选顶点为F,对应距离为6。因此选取距离最短的边(B,F),标记F,并将F添加至集合U中。

(6)集合U中顶点有A、B、C、D、F。顶点A、B、D均无可选顶点。顶点C可选顶点为E,对应距离为8。顶点F可选顶点为E,对应距离为7。选取距离最短的边(F,E),标记E,将E添加至集合U中。

(7)集合U中顶点有A、B、C、D、E、F,但是均没有可选顶点,树的生成过程结束。

3.3 性能分析

  Prim算法使用邻接矩阵来保存图的话,时间复杂度是O(N2),使用二叉堆优化Prim算法的时间复杂度为O((V + E) log(V)) = O(E log(V))。

4 克鲁斯卡算法——Kruskal算法

4.1 算法流程

  (1)把图中的所有边按代价从小到大排序。
  (2)把图中的n个顶点看成独立的n棵树组成的森林。
  (3)按权值从小到大选择边,所选的边连接的两个顶点ui,vi。ui,vi应属于两颗不同的树,则成为最小生成树的一条边,并将这两颗树合并作为一颗树。
  (4)重复步骤(3),直到所有顶点都在一颗树内或者有n-1条边为止。

4.2 算法图解

例如:图4.2所示的无向图,采用Kruskal算法构建最小生成树过程如下。

(1)首先将所有的边按照代价大小进行排序,排序结果为(B,D),(B,F)(A,C),(B,C),(A,B),(D,F),(E,F),(C,E)。

(2)代价最小边为(B,D),顶点B、D不在同一棵树上,将顶点B、D合并到一棵子树。

(3)代价最小边为(B,F),顶点B、F不在同一棵树上,将顶点B、F合并到一棵子树。

(4)代价最小边为(A、C),顶点A、C不在同一棵树上,将顶点A、C合并到一棵子树。

(5)代价最小边为(B,C),顶点B、C不在同一棵树上,将顶点B、C合并到一棵子树。

(6)代价最小边为(A,B),顶点A、B在同一棵树上,因此不能选择此边。

(7)代价最小边为(D,F),顶点D、F在同一棵树上,因此不能选择此边。

(8)代价最小边为(E,F),顶点E、F不在同一棵树上,将顶点E、F合并到一棵子树。

top Created with Sketch.