图的最小生成树算法

生成树:一个连通图的生成树是指一个极小连通子图,含有图中的全部n个顶点,但只有足以构成一棵树的n-1条边。

构造网的一棵最小生成树,即:在e条带权的边中选取n-1条边,不构成回路,使“权值之和”最小。
最小生成树要解决的问题:

  1. 尽可能选取权值小的边,但不能构成回路;
  2. 选取n-1条恰当的边以连接网的n个顶点。

Prim算法(普里姆算法)

Prim算法思想

取图中任意一个顶点v作为生成树的根,之后往生成树上添加新的顶点w,注意添加的这个顶点要使该边的权值在所有连通顶点v和w之间的边中取值最小。之后继续往生成树上添加顶点,直至生成树上含有n个顶点为止。

一般情况下所添加的顶点应满足条件:
在生成树的构造过程中,图中n个顶点分属两个集合:已落在生成树上的顶点集U和尚未落在生成树上的顶点集V-U;则应在所有连通U中顶点和V-U中顶点的边中选取权值最小的边。

看例子。首先,选择一个顶点a在生成树U中,
在这里插入图片描述
要保证权值最小,选e,d,c,b,然后选择g,
在这里插入图片描述
剩下的里面权值18,16,21,最小的,就是16了,所以选g。g和f之间27,d 和f之间21,最后选中f。
在这里插入图片描述
连通网用带权的邻接矩阵表示,并设置一个辅助数组closedge[],数组元素下标对应当前V-U集中的顶点序号,元素值则记录该顶点和U集中相连接的代价最小(最近)边的顶点序号adjvex和权值lowcost。即对v∈V-U的每个顶点,closedge[v]记录所有与v邻接的、从U到V-U的那组边中的最小边的信息。
在这里插入图片描述
简单来说,就是先任取一点a作为生成树的根,选了就把1a的lowcost置为0,然后选它的邻点,考虑2b,5e,7g,将它们的adjvex置为1a,lowcost填入权值,选取最小权值的5e,将其lowcost置0,以此类推下去,后面选的点的adjvex填入从哪个点过来的,如下图所示。
在这里插入图片描述

struct{ 
	vertexData adjvex; 
	int lowcost; 
}closedge[MAX_VERTEX_NUM];

MiniSpanTree_Prim(AdjMatrix gn, VertexData u){//邻接矩阵的网,选中作为生成树根的点
	k=LocateVertex(gn,u);//确定根在网里的下标 
	closedge[k].lowcost=0; 
	for(i=0;i<gn.vexnum;i++)//将剩下的n-1个点加入集合中
		if(il=k){
			closedgclil.adjvex=u; 
			closcdgc/i].lowcost=gn.arcs/kllil.adj;//只要当前节点不是出发点,就把那一行都填为出发点
		}
	for(e=1;e<=gn. vexnum-1;e++){
		kO=Minium(closedge); 
		u0=closedge[k0].adjvex; 
		v0=gn.vexs[k0]; 
		printf(uO,v0); 
		closedge[k0].lowcost=0;
		for(i=0;i<vexnum;i++)
		if(gn. arcs/kOllil.adj < closedge[i].lowcost){
			closedge[i].lowcost=gn.arcs[k0][i].adj;
			closedgeli].adjvex=vo;
		}
	}
}		

外层循环n-1次,内层n次,时间复杂度为O(n2),这个算法适合顶点数少的网络,即稠密图

Kruskal算法(克鲁斯卡尔算法)

为使生成树上边的权值之和达到最小,则应使生成树中每一条边的权值尽可能地小。
具体做法:先构造一个只含n个顶点的子图SG,然后从权值最小的边开始,若它的添加不使SG中产生回路则在SG上加上这条边,如此重复,直至加上n-1条边为止。也称为加边法。

举例说明,先将所有的边按权值从小到大排序,写出只含所有顶点的子图,
在这里插入图片描述
然后从权值最小的边开始,往子图里添加。
在这里插入图片描述
在这里插入图片描述
(C,D)加进去就会产生回路,说明C,D已经在边集里面了,删掉这条边,然后继续,直到所有点都加入顶点集,n-1条边加入边集,最后得到红色部分的就是最小生成树:
在这里插入图片描述
Kruskal算法权值排序用到堆排序算法,后面才会讲到,还有要判断是否有回路产生,所以算法具体实现这里就不赘述了。Kruskal算法更适合于顶点多而边数少的稀疏图

图的生成树不唯一,从不同的顶点出发进行遍历,可以得到不同的生成树;
即使从相同的顶点出发,在选择最小边时,可能有多条同样的边可选,此时任选其一。

比较两种算法:

算法名 普里姆算法 克鲁斯卡尔算法
时间复杂度 O(n2) O(eloge)
适应范围 稠密图 稀疏图

猜你喜欢

转载自blog.csdn.net/ITmincherry/article/details/106167673
今日推荐