先看一下下面这张图。
算法思想:可取图中任意一个顶点V作为生成树的根,之后若要往生成树上添加顶点W,则在顶点V和W之间必定存在一条边。并且该边的权值在所有连通顶点V和W之间的边中取值最小。
一般情况下,假设n个顶点分成两个集合:U(包含已落在生成树上的结点)和V-U(尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边
下面是其C语言算法实现:
//最小生成树 普里姆算法 采用邻接矩阵存储 void MiniSpanTree(MGraph *G) { int min, i, j, k; int adjvex[MaxVex]; //保存相关顶点下标 int lowcost[MaxVex]; //保存相关顶点间边的权值 lowcost[0] = 0; //初始化第一个权值为0,即V0加入生成树 adjvex[0] = 0; //初始化第一个顶点下标为0 //初始化操作 for (i=1; i<G->numVertexes; ++i) { lowcost[i] = G->arc[0][i]; adjvex[i] = 0; //将v0顶点与之有边的权值存入数组 并初始化都为v0的下标 } //adjvex[i],i是其他节点的标记,adjvex[i]=0即是把0~n的节点都与节点0关联起来 for (i=1; i<G->numVertexes; ++i) { min = INFINITY; j = 1; k = 0; //保存权值最小的顶点 //遍历v-u集合中剩下的节点 while (j<G->numVertexes) { //如果两个顶点之间存在边并且权值小于min if (lowcost[j]!=0 && lowcost[j]<min) { min = lowcost[j]; k = j; } ++j; } printf("(%d, %d)", adjvex[k], k); //输出当前顶点边中权值最小的边 lowcost[k] = 0; //将当前顶点的权值设为0,表示此顶点已经完成任务 //更新新节点与其他节点之间的最小花费和关联 for (j=1; j<G->numVertexes; ++j) { if (lowcost[j]!=0 && G->arc[k][j]<lowcost[j]) { lowcost[j] = G->arc[k][j]; adjvex[j] = k; } } } }