最小生成树算法——普里姆算法
【摘要】 普里姆算法
假设G=(V,E)是一个具有n个顶点的连通网,T=(U,TE)是G的最小生成树,其中U是T的顶点集,TE是T的边集,U和TE的初始值为空。算法过程:
首先从V中任取一个顶点(假定v1),将它并入U中,此时U={v1}然后只要U是V的真子集(即U⊂V),就从那些一个端点已在T中,别一个端点仍在T外的所有边中,找一条最短(即权值最小)边,假定为(vi,vj)...
普里姆算法
假设G=(V,E)是一个具有n个顶点的连通网,T=(U,TE)是G的最小生成树,其中U是T的顶点集,TE是T的边集,U和TE的初始值为空。算法过程:
- 首先从V中任取一个顶点(假定v1),将它并入U中,此时U={v1}
- 然后只要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算法的步骤:
1.将顶点集合分成两个部分——U(选中的部分),V(未选中的部分)
2.每次从两个部分中找出权值最小的边
3.相连的顶点划入U中
4.重复1,直到顶点全部划入U中。
为了方便实现算法,附设一个辅助数组minedge[vtxptr],记录从U到V-U具有最小代价的边(即权值最小的边)。对每个顶点v∈V-U,在辅助数组中存在一个minedge[v]分量。每个分量包括两个域:ver域存储该边附在U中的顶点,lowcost域则存储该边上的权值。
具体算法如下:
#include <stdio.h>
// 最大顶点数
#define MaxVertexNum 50
typedef char VertexType;
typedef int Adjmatrix;
// 邻接矩阵
typedef struct { VertexType vex[MaxVertexNum];// 顶点数组,类型假定为char Adjmatrix arcs[MaxVertexNum][MaxVertexNum];// 邻接矩阵,类型假定为int
}MGraph;
typedef int VRType;
typedef struct{ VertexType ver; VRType lowcost;
}MinEdge[MaxVertexNum];
MinEdge minedge;// 从顶点集U到V-U的代价最小的边的辅助数组
// 返回顶点u在MGraph的vex数组中的下标,以此作为顶点u在辅助数组中的下标
// 若G中存在顶点u,则返回该顶点在图中的位置;否则返回-1
int vtxNum(MGraph G,int u,int n){ // u是顶点,n是图G的顶点总数 int k; for(k = 0;k < MaxVertexNum;k++){ if(G.vex[k] == u){ return k; } } return -1;
}
int min(MGraph G,MinEdge MINI,int n){ int i=0,j,k,min; while(!MINI[i].lowcost){ i++; } min = MINI[i].lowcost;// 第一个不为0的值 k=i; for(j = i+1;j < n;j++){ if(MINI[j].lowcost > 0 && MINI[j].lowcost<min){ min = MINI[j].lowcost; k=j; } } return k;// 返回最小值在辅助数组中的序号
}
void prim(MGraph G,VertexType u,int n){ // G是采用邻接矩阵存储结构表示的图,u是顶点,n是顶点个数,以u作为出发点 int k,v,j; k=vtxNum(G,u,n);// 取顶点u在辅助数组中的下标 for(v = 0;v<n;v++){// 辅助数组初始化,v是每个顶点,此处是初始顶点u与顶点v的关系 if(v!=k){ minedge[v].ver = u;//顶点域全部赋值为u点 minedge[v].lowcost = G.arcs[k][v];//距离域全部赋值为u到其他点的距离 } } // 初始化,U={u} minedge[k].lowcost = 0; for(j = 0;j < n;j++){ k=min(G,minedge,n);//k为辅助数组中值最小的点对应的序号 printf("edge:%d-%d",minedge[k].ver,G.vex[k]);// 输出生成树的边 minedge[k].lowcost = 0;// 第k顶点并入U集合 for(v=0;v<n;v++){ if(G.arcs[k][v] < minedge[v].lowcost){ // 新顶点并入U集合后,重新选择最小边 minedge[v].ver=G.vex[k]; minedge[v].lowcost=G.arcs[k][v]; } } }
}
推荐看一个视频:https://b23.tv/BV19J411n76b
文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/weixin_40763897/article/details/105487546
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)