并查集

在一些有N个元素构成的一些单元素的集合,需要反复查找一个元素在哪一个集合中,判断两个数是否属于同一个集合,以及合并两个集合。并查集是一种树型的数据结构。用于处理不相交的集合( disjoint sets)的合并以及查询问题。在使用时用森林表示。

如集合A={0,1,3,6} , B={ 2,4 7} , C={5,8,9}其A,B,C分别构成三棵树,A,B,C共同构成一个森林,并查集一般用数组存储,如数组father。father[i]表示i的父节点,当father[x]==x时,表示x是根结点。在查找元素属于哪一个集合时,采用路径压缩的办法,可以避免树退化为线性,以保证查找的效率。它使用的O(n)的空间,单次查找时间为O(a(n)),一般可认为是常数:

以下是A,B,C集合在father数组的存储:

00
10
22
30
42
55
60
72
85
95

#include<iostream>
using namespace std;
#define n 11
int father[n] = {0,0,2,0,2,5,0,2,5,5,9};
int getRoot(int x);
int Union(int x, int y);
int main(){
	/*测试*/
	int i,j;
	cin >> i;
	i = getRoot(i);
	cout << i << endl;
	Union(1, 10);
	cin >> i;
	i = getRoot(i);
	cout << i << endl;
	return 0;
}
int getRoot(int x){
	int j = x,i;
	while (father[x] != x)         /*向上寻找根结点*/
		x=father[x]; 
	while (father[j] != x){      /*状态压缩*/
		i = father[j];          /*记住j的父节点i*/
		father[j] = x;          /*将j直接连到根结点*/
		j = i;                  /*更新j为j原来的父节点*/
	}
	return x;                 // 返回根结点
}
int Union(int x, int y){
	x = getRoot(x);
	y = getRoot(y);  
	if (x != y) 
		father[x] = y;
	return y;          //返回最后合并的根结点
}
以上查找还可以使用递归的写法,这样getRoot函数如下:

int getRoot(int x){
	if (father[x] != x)
		father[x] = getRoot(father[x]);     //状态压缩,将沿途结点都连接到根结点后
	return father[x];                      // 返回根结点
}



以下实现集合的查找以及集合的并:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值