序言
假设要在n个城市之间建立一个通信联络网,则联通 n 个城市只需要 n-1 条线路。这时,自然会考虑这样一个问题,如何在最节省经费的前提下建立这个通信网。在每两个城市之间都可以设置一条线路,相应的都要付出一定的经济代价。n 个城市之间,最多可能设置 n(n - 1) / 2 条线路,那么,如何在这些可能的线路中选择 n - 1 条,以使总的耗费最少呢?这个问题就是构造连通网的最小代价生成树(Minimun Cost Spanning Tree)(简称为最小生成树)问题。一棵生成树的代价就是树上各边的代价之和。
连通图
普里姆(prim)算法
假设 N = (V, {E}) 是连通网, TE 是 N 上最小生成树中边的集合。算法从 U = {u。}(u。∈ V), TE = { } 开始,重复执行下述操作:在所有 u∈U,v∈V - U 的边(u, v)∈ E中找到一条代价最小的边 (u。, v。)并入集合 TE, 同时 v。并入U,直至 U=V 为止。此时 TE 中必有 n-1 条边,则T=(V, {TE})为 N 的最小生成树。
克鲁斯卡尔(Kruskal)算法
克鲁斯卡尔算法从另一途径求网的最小生成树。假设连通网 N=(V, {E}),则另最小生成树的初始状态为只有 n 个顶点而无边的非连通图 T=(V, { }),图中每个顶点自成一个连通分量。在 E 中选择代价最小的边,若该边依附的顶点落在 T 中不同的连通分量上,则将此边加入到 T 中,否则舍去此边而选择下一条代价最小的边。依此类推,直至 T 中所有顶点都在同一连通分量上为止。
算法分析
普里姆算法的时间复杂度为O(n2),与网中的边数无关,因此适用于求边稠密的网的最小生成树。而克鲁斯卡尔算法恰恰相反,它的时间复杂度为O(elog(e))(e为网中边的数目),因此它相对于普里姆算法而言,适合于求边稀疏的网的最小生成树。
参考书目
《数据结构(C语言版)》 严蔚敏 吴伟民 编著 清华大学出版社