算法导论学习笔记-第二十三章-最小生成树

来源:互联网 发布:周扬青 淘宝直播 编辑:程序博客网 时间:2024/06/07 06:06

第二十三章 最小生成树

 

总结:这一章介绍了最小生成树,并介绍了找出最小生成树的两个算法,Prim算法和Kruskal算法,它们都用到了贪心策略。

 

1.    最小生成树

对无向连通图G=(V,E),对图中的每一条边(u,v)єE,都有一个权值w(u,v)。我们希望找出一个无回路的子集T包含于E,它连接了所有的顶点,且其权值之和w(T)=Σw(u,v)为最小。把确定T的问题称为最小生成树问题。

 

2.    Kruskal算法

用了并查集和贪心策略的思路。初始时,所有结点各自为一个集合。先从众多边中,找出权值最小的那条边(u,v),如果这条边属于同一个集合,则说明u,v已经联结在一起了,就不用添加了,否则,就是用最小的代价将两个结点所属的集合合并,这样一直下去即可。

 

运行时间:O(ElgV)

 

伪代码

Kruskal(G,w)

A <- 空集

for each vertex vєV[G]

      do MAKE-SET(v)

sort the edges of E into nondecreasing order by weight w

for each edge(u,v) є E, taken in nondecreasing order by weight

      do if FIND-SET(u)!=FIND-SET(v)

                 then A <- A U {(u,v)}

                       UNION(u,v)

return A

 

3.    Prim算法

先选一个点,找出与该点邻接的所有边中最小的那一条,然后将新的结点添加进去,再找与新的集合中那些点相邻接的所有边中最小的那一条,添加进去,这样依次下去,形成一颗最小生成树。

在算法的执行过程中,不在树中的所有顶点都放在一个基于key域的最小优先级队列Q中。对每个顶点vkey[v]是所有将v与树中某一顶点相连的边中的最小权值;若不存在这样的边,则key[v]=无穷大。

 

运行时间:O(V*EXTRACT-MIN()+E*DECREASE-KEY())

             使用二叉最小堆: O(VlgV+ElgV)=O(ElgV)

             使用斐波那契堆: O(VlgV+E)

 

伪代码

MST-PRIM(G,w,r) //r为选择的最初的顶点

for each uєV[G]

      do key[u] <- 无穷大

         pi[u] <- NIL //pi[u]指在最小生成树中u的父亲结点

key[r] <- 0

Q <- V[G]

while Q!=

      do u <- EXTRACT-MIN(Q)

           for each vєAdj[u]

                 do if vєQ and w(u,v) < key[v]

                      then pi[v] <- u

                             key[v] <- w(u,v)

 

原创粉丝点击