Prim算法简单实现如下:
G=(V,E); //V顶点集合,E边结合
void Prim(G){
T=∅ //初始化空树
U={w}; //添加任意顶点w
while((V-U)!=∅){ //若树中不包含全部顶点
//设(u,v)是u∈U,v∈(V-U),且权值最小的边
T=T∪{(u,v)} //边并入树
U=U∪{v} //顶点并入树
}
}
prim算法实现过程:
C实现:
//邻接矩阵
typedef struct{
//int vex[MVNum];
int arc[MVNum][MVNum];
int vexnum, arcnum;
}AMGraph;
int LocateVex(AMGraph *G,VerTexType v){
for(int i=0;i<G->vexnum;i++){
if(G->vex[i]==v)
return i;
}
return -1;
}
int CreateGraph()
{
MGraph* G;
G->vexnum=x;
G->arcnum=x;
//初始化为无穷
for(i=0;i<G->vexnum;i++){
for(j=0;j<G->vexnum;j++)
G->arc[i][j]=MAX;
}
//将边和权值写到邻接矩阵中,连通即为权值,否则为无穷大
for(k=0;k<G->arcnum;k++){
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G->arc[i][j]=weight;
}
}
Prim算法:
//三个关键数组:adjvex[],lowcost[],S[]
//共N个节点
void Prim(AMGraph *G, int k){
//记录所有已标记结点中到结点i的最短距离lowcost[i],每次加入新节点更新
int lowcost[G->vexnum];
memcpy(lowcost,G->arc[k],G->vexnum*sizeof(int));
//记录lowcost[]对应的已标记结点
int adjvex[G->verxnum];
memset(adjvex,k,G->vexnum*sizeof(int));
//当前已标记结点中到结点i的最短边为(adjvex[i],i),权值lowcost[i]
//标记有没有访问过
bool S[G->vexnum];
memset(S,false,sizeof(S));
S[k]=true; //将自己加进去
for(i=0;i<G->vexnum-1;i++){ //循环N-1次
//找出lowcost[]里没别访问过的最小值
min=MAX;
for(j=0;j<G->vexnum;j++){
if(!S[j]&&min>lowcost[j]){
min=lowcost[j];
v=j;
}
}
//这里没有对最后min==MAX的情况做处理,有需要在修改
//找出边(adjvex[v],v)
//注意点:这里只用将v标记为已读,adjvex[v]不用,因为adjvex[]的更新的都是刚加入的结点,27,31行
S[v]=true;
//用新加入的节点更新lowcost[],和对应的adjvex[]
for(j=0;j<G->vexnum;j++){
if(lowcost[j]>G->arc[v][j]){
adjvex[j]=v;
lowcost[j]=G->arc[v][j];
}
}
}
}
Prim和Dijkstra的对比:
两个算法非常相似,基本思路都是一样的,只有对最短距离数组的更新不一样;
Prim算法是加入新节点v之后,直接比较v到其他未访问过结点距离与当前最短距离,进行更新;
Dijkstra算法是找出结点v为当前最短,比较以v为中继到其他未访问结点的距离与当前最短距离,进行更新。
都是遍历最短距离数组,找出没有被访问过的最小距离结点,再通过刚找到的结点更新最短距离数组,循环N-1次,可以对比着学习==>Dijkstra算法;