并查集算法

本文介绍了并查集数据结构及其在解决元素分组问题中的应用,包括朴素版本的实现、路径压缩优化查询效率,以及按秩合并策略降低合并操作对树高度的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概念

1.并查集:用于解决元素分组问题,管理一系列不相交的集合

2.两个关键函数:合并 + 查询

3.思想:

f[i]:存i的父节点,令根节点的f[i]等于其本身

合并时,将其中一个根节点的父节点设为另一个节点的根节点即可

查询时,根据f[]判断,f[a] == f[b]

朴素版

int f[n];
//初始化,所有节点都看成根节点
void init()
{
	for(int i = 0;i < n;i ++) f[i] = i;
}
//查询
int find(int x)
{
	if(f[x] == x) return x;
	else return find(f[x]);
}
//合并
void merge(int a,int b)
{
	f[find(a)] = find(b);
}

路径压缩

在查询、合并时,都只需要关心根节点。所以,在查询时,将每个节点的父节点都设为根节点。

int find(int x)
{
	if(f[x] == x) return x;
	else
	{
        //在查询时,沿途将所有节点的父节点设置为根节点
		f[x] = find(f[x]);
		return f[x];
	}
}

按秩合并

当一个深度为7的树和一个元素合并时,显然将一个元素合并到树上更合适,反之,会增加树的高度,增加复杂度

r[i] :以 i 为根节点的树的深度

1.初始化:r[ ] = 1

2.合并:

(1)找到各自的根节点

(2)根据根节点的r[]大小进行合并

(3)如果两个根节点的秩相同,且合并的两个节点不在一个集合上时,合并时,应将合并后根节点的秩+1

void init()
{
	for(int i = 0;i < n;i ++)
	{
		f[i] = i;
		r[i] = 1;
	}
}
int merge(int a,int b)
{
	int fa = find(a),fb = find(b);
	if(r[fa] >= r[fb]) f[fb] = fa;
	else f[fa] = fb;
	
    //在秩相等时,处理成b合并到a上
	if(r[fa] == r[fb] && a != b) r[fa] ++;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值