您的位置:首页 > 其它

最小生成树-Prim

2011-05-04 16:51 183 查看
Prim算法思想

假设G=(V,E)是一个具有n个顶点的连通网,T=(U,TE)是G的最小生成树,其中,U是T的顶点集,TE是T的边集。Prim算法的基本思想是:令集合U的初值为U={v0}(v0是从V的任取的一个顶点,也就是说构造最小生成树时从v0开始),集合TE的初值为TE={}。然后只要U是V的真子集(即U∈V),就从哪些其一个端点已在T中,另一个端点仍在T外的所有边中,找一条最短(即权值最小)边,假定为(vi,vj),其中vi∈U,vj∈(V-U),并把该边(vi,vj)和顶点vj分别并入T的边集TE和顶点集U,如此进行下去,每次往生成树里并入一个顶点和一条边,直到n-1次后就把所有n个顶点都并入到生成树T的顶点集中,此时U=V,TE中含有n-1条边,T就是最后得到的最小生成树。

显然,Prim算法的关键之处是:每次如何从生成树T中到T外的所有边中,找出一条最短边。

#define MAX_EDGE_NUM 100			//最大边的个数
typedef struct {
int fromvex;					//边的起点域
int endvex;						//边的终点域
VRType weight;					//边的权值域
}edge,edgeset[MAX_EDGE_NUM];		//边集数组类型

void Prim( MGraph G, edgeset CT )
{	//利用Prim算法从顶点v0出发求出用邻接矩阵G表示的图的最小生成树,
//最小生成树的边集存入数组CT中
int i,j,k,t,m,w;
VEType min;
for( i=0; i<G.vexnum-1; i++ )
{
CT[i].fromvex = 0;
CT[i].endvex = i + 1;
CT[i].weight = G.arcs[0][i+1].adj;	//给CT赋初值,对应第0次的LW值
}
for( k=1; k<G.vexnum; k++ )				//每次循环求出最小生成树中的第k条边
{
min = MAX_VALUE;					//从CT[k-1]~CT[G.vexnum-2](即LW)中查找最短边CT[m]
m = k - 1;
for( j=k-1; j<G.vexnum-1; j++ )
if( CT[j].weight < min )
{
min = CT[j].weight;
m = j;
}
edge temp = CT[k-1];				//把最短边对调到第k-1下标位置
CT[k-1] = CT[m];
CT[m] = temp;
j = CT[k-1].endvex;					//把新并入最小生成树T中的顶点序号赋给j
//修改LW中的有关边,使T中到T外的每一个顶点个保持一条最短边
for( i=k; i<G.vexnum-1; i++ )
{
t = CT[i].endvex;
w = G.arcs[j][t].adj;
if( w<CT[i].weight )
{
CT[i].weight = w;
CT[i].fromvex = j;
}//if
}//for(i=k...)
}//for(k=1...)
}//Prim
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: