最小生成树-克鲁斯卡尔方法(Kruskal)-C语言实现

克鲁斯卡尔方法(Kruskal):不断将最小的但不会构成回路的边并入树。


示例如下:



判断是否构成回路要用到并查集,并查集可快速查找要并入的边与当前的树是否为同一集合(是否在同一棵树中),若为同一集合(在同一棵树中)则会构成回路。

并查集的实现方式为:并查集v[a]用来存放a的双亲结点,当a ==v[a]时为根节点,可通过语句"while(a != v[a]) a = v[a];"从a出发最终得到的a',为最初的a的根节点。当两个结点的根节点相同时a ==b,则产生回路。


C代码如下:

struct Road{		//简易的定义一条边
	int a, b;	//一条边的两个顶点
	int w;		//边的权值
};
Road road[m];
int v[maxSize] = {0};		//定义并查集数组

int getRoot(int a)		//在并查集中找根节点的函数
{
	while(a != v[a]) a = v[a];		//自己为自己双亲时,为根节点
	return a;
}

void Kruskal(MGraph g, int &sum, Road road[])	//克鲁斯卡尔方法
{
	int i, a, b;
	sum = 0;
	for(i = 0; i < g.n; ++i) 
   v[i] = i;	//各自为根节点(一棵树)
	sort(road, g.e);			//对所有边进行排序
	for(i = 0; i < g.e; ++i){	//排过序的边依次判断
		a = getRoot(road[i].a);
		b = getRoot(road[i].b);
		if(a != b){		//不同根时,将该边并入(此时不会形成回路)
			v[a] = b;	// b成为a的双亲结点
			sum += road[i].w;
		}
	}
}





评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值