Prim算法求最小生成树

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算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值