最小生成树——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为网中边的数目),因此适合于求边稀疏的网的最小生成树。
posted @ 2021-11-28 17:48  某科学的撒把豆子  阅读(630)  评论(0)    收藏  举报