最小生成树——Prim(普里姆)算法
一、算法思想:
①从图中任意取出一个顶点,把它当做一棵树。
②然后从这棵树相接的边中选取一条最短(权值最小)的边,并将这条边及其所连接的顶点也加入到这棵树中,此时得到了一棵有两个顶点的树。
③然后从这棵树相接的边中选取一条最短(权值最小)的边,并将这条边及其所连接的顶点也加入到这棵树中,得到一棵有三个顶点的树。
④以此类推,直到图中所有顶点都被并入树中为止,此时得到的生成树就是最小生成树。
辅助变量:
vest[]:vest[i]=1表示顶点Vi已经被并入到生成树中,vest[i]=0表示顶点Vi还没有被并入生成树中。
lowcost[]:对于i,lowcost[i]中保存的是当前生成树到顶点Vi的多条边中最短的一条边的权值。
二、伪代码如下:
1 #define MAXSIZE 100 2 void Prim(MGraph G, int v0, int &sum){ 3 /*从这句开始对各变量进行初始化*/ 4 int lowcost[MAXSIZE],vest[MAXSIZE],v; 5 int i,j,k,min; 6 v = v0; 7 for(i = 0; i < G.vertex_num; ++i){ 8 lowcost[i]=G.edgs[V0][i]; 9 vest[i] = 0; 10 }//for 11 vest[V0] = 1; //将V0并入书中 12 sum = 0; //sum清零用来累计树的权值 13 /*初始化结束,开始Prim算法主过程*/ 14 for(i = 0; i < G.vertex_num - 1; ++i){ 15 min = INF; 16 /*下面这个循环用于选出候选边中的最小者*/ 17 for(j = 0; j < G.vertex_num; ++j) 18 if(!vest[j] && lowcost[j] < min){ 19 min = lowcost[j]; 20 k = j; 21 }//if 22 vest[k] = 1; 23 v = k; 24 sum += min; //这里用sum记录了最小生成树的权值 25 /*下面这个循环以刚并入的顶点v为媒介更新候选边*/ 26 for(j = 0; j < G.vertex_num; ++j) 27 if(!vest[j] && (G.edges[v][i] < lowcost[j])) 28 lowcost[j] = G.edges[v][j]; 29 }//for 30 }//Prim
三、算法性能分析:
时间复杂度:Prim算法的执行非常类似于寻找图的最短路径的Dijkstra算法。
时间复杂度为O(V^2),不依赖于e,因此它适用于求解边稠密的最小生成树。
虽然采用其他方法能改进Prim算法的时间复杂度,但也增加了实现的复杂性。
四、Kruskal(克鲁斯卡尔算法)
时间复杂度:Kruskal算法的时间复杂度为O(eloge)(e为网中边的数目),因此适合于求边稀疏的网的最小生成树。

浙公网安备 33010602011771号