并查集~~

并查集的定义

取自:Union、Find、Set
功能:
1、合并:合并两个集合
2、查找:判断两个元素是否在一个集合内
实现方式:数组

int father[N];

father[i]:表示i的父亲结点。
father[i] = i由于一个集合中只能有一个根结点,且将其作为所属集合的标识。

并查集的基本操作

1、初始化

for(int i = 1; i <= N; i++){
	father[i] = i;
}

2、查找
由于规定同一个集合中只能有一个根结点,所以查找操作就是对给定的结点寻找其根结点的过程。

int findFather(int x){
	while(x != father[x]){
		x = father[x];
	}
	return x;
}

也可以用递归实现哈~

int findFather(int x){
	if(x == father[x])	return x;
	else	return findFather(father[x]);
}

3、合并
判断两个元素,如果是不同集合,那就合并。一般来说,一个集合的根结点的父结点会指向另一个集合。

思路~
1、对于两个结点,先判断其根结点是否相同(可以调用上面的函数)。
2、合并两个集合:在1、中获取的两个集合的根结点faA和fbB,只需要把其中一个的父亲结点指向另一个结点就可以了。

代码如下~

void Union(int a, int b){
	int faA = findFather(a);
	int faB = findFather(b);
	if(faA != faB)
		father[faA] = faB;
}

并查集的一个性质:
在合并的过程中,只对两个不同的集合进行合并,如果两个元素在相同的集合中,那就不会对它们进行操作。这就保证了在同一个集合中一定不会产生画面,即并查集产生的每一个集合都是一棵树。

路径压缩

请添加图片描述
因为只需要寻找根结点,所以用上图的方法更快找到。O(1)
实现转换的步骤:
1、按照原先的方法获取x的根结点。
2、重新从x走一遍寻找根结点的过程,把路径上经过的所有结点的父亲结点全都改为根结点r
代码如下~

int findFather(int x){
	int a = x;
	while(x != father[x])
		x = father[x];
	
	while(a != father[a]){
		int z = a;
		a = father[a];
		father[z] = x;
	}
	return x;
}

以下为递归操作~

int findFather(int v){
	if(v == father[v]){
		return v;
	}else{
		int F = findFather(father[v]);
		father[v] = F;
		return F;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾尔伯特想变瘦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值