算法作业1.2-----用Kruskal算法构造最小生成树

Kruskal算法

Kruskal算法(克鲁斯卡尔算法)是一种用来查找最小生成树的算法。

算法描述

先构造一个只含 n 个顶点、而边集为空的子图,把子图中各个顶点看成各棵树上的根结点,之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,即把两棵树合成一棵树,反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直到森林中只有一棵树,也即子图中含有 n-1 条边为止。

算法步骤

1、新建图G,G中拥有原图中相同的节点,但没有边;
2、将原图中所有的边按权值从小到大排序;
3、从权值最小的边开始,如果这条边连接的两个节点于图G中不在同一个连通分量中(即不构成环状),则添加这条边到图G中;
4、重复3,直至图G中所有的节点都在同一个连通分量中。

算法图解

在这里插入图片描述
以上图为例,先新建一个新图G,G拥有上图的节点却没有边。

在这里插入图片描述
再将所有边按照权值从小到大的排序。

权值
B–D2
A–B3
D–F3
C–F4
E–G5
A–E6
B–H7
B–G8
G–H10
F–H11
A–C12

从权值最小的B–D边开始加入图中

在这里插入图片描述
重复将边加入,但不能构成环状,如果构成环状则丢弃该边。
在这里插入图片描述
加入D–F边
在这里插入图片描述
加入C–F边
在这里插入图片描述
加入E–G边
在这里插入图片描述
加入A–E边
在这里插入图片描述
加入B–H边,在加入B–H边之后所有顶点已经联通,所以最小生成树构造完成。
在这里插入图片描述

算法设计

算法主要分为
1、排序函数sort,用来将所以图的权值边进行由大到小的排序
2、将边加入图中,使用并查集进行检查是否为同一联通分量。

void sort(Road data, int n)
{
	int i , j;
	for(i 从 1 到 n-1){
		for(j 从 1 到 n-i){
			if(data[j].w > data[j+1].w)//从小到大排序
			{
				road t = data[j];
				data[j] = data[j+1];
				data[j+1] = t;
			}
		}
	}
}
int getRoot(int v[], int x)  //查询该边所对应的顶点在并查集中是否同源
{
	while (v[x] != x){
		x = v[x];
	}
	return x;
}
int Kruskal(Graph g)
{
	int sum = 0;
	int v[Max];//建立并查集
	int i;
	for(i = 1 ; i <= g->n ; i++)//初始化并查集
	{
		v[i] = i;
	}
	sort(g->data , g->e);//排序
	for(i = 1 ; i <= g->e ; i++){
		int a , b;
		a = getRoot(v,g->data[i].a);//在并查集中查找是否为同源
		b = getRoot(v,g->data[i].b);
		if(a != b)
		{
			v[a] = b;
			sum += g->data[i].w;
		}
	}
	return sum;
}

源码
https://github.com/Lu-ziyan/-/blob/master/kruskal.cpp

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值