首页 » 技术分享 » 克鲁斯卡尔(Kruskal)算法

克鲁斯卡尔(Kruskal)算法

 

克鲁斯卡尔(Kruskal)算法

最小生成树

一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。 [1] 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。
“最小生成树”百度词条

构造最小生成树的算法的基本原则

  • 尽可能选取权值最小的边,但不能构成回路
  • 选择n-1条边构成最小生成树

克鲁斯卡尔算法思想

设G=(V,E)是具有n个顶点的连通网,T=(U,TE)是其最小生成树。

  • 1、选取权值最小的边(Vi,Vj),若边(Vi,Vj)加入到TE后形成回路,则舍弃该边,否则将该边加入到TE中。
  • 2、重复1,知道TE中含有n-1条边为止

实例(转载)

同大话数据结构上的实例
实例(转载)

MSTEdge * Kruskal_MST(ELGraph * G)
/*用Kruskal算法构造图G的最小生成树*/
{
MSTEdge TE[];
int j,k,v,s1,s2,Vset[];
WeightType w;
Vset=(int *)malloc(G->vexnum*sizeof(int));
for(j=0;j<G->vexnum;j++)
	Vset[j]=j;/*初始化数组Vset[n]*/
sort(G->edgelist);/*对表按权值大小排序*/
j=0;k=0;
while(k<G->vexnum-1&&j<G->edgenum){
	s1=Vset[G->edgelist[j].vex1];
	s2=Vset[G->edgelist[j].vex2];
	/*若边的两个顶点的连通分量编号不同,边加入到TE中*/
	if(s1!=s2){
	TE[k].vex1=G->edgelist[j].vex1;
	TE[k].vex2=G->edgelist[j].vex2;
	TE[k].weight=G->edgelist[j].weight;
	k++;
	for(v=0;v<G->vexnum;V++)
		if(Vset[v]==s2)	Vset[v]=s1;
	}//if#
	j++;
	}//while#
	free(Vset);
	return(TE);
}

克鲁斯卡尔算法操作分为【对边的权值排序部分】和【一个单重for循环】,它们是并列关系,由于排序耗费时间大于单重循环,所以克鲁斯卡尔算法的时间主要耗在排序上。排序和图中边的数量有关,因此适合稀疏图。

转载自原文链接, 如需删除请联系管理员。

原文链接:克鲁斯卡尔(Kruskal)算法,转载请注明来源!

0