并查集
并查集是一种树形的数据结构,顾名思义,它用于处理一些不交集的 合并 及 查询 问题。 它支持两种操作:
查找(Find):确定某个元素处于哪个集合。
合并(Union):将两个集合并成一个集合。
查找思想:
- 一棵树的根结点可以代表这棵树的所有元素,即查找过程,已知一棵树中的元素通过查找树的根结点,就可以确定这个元素属于哪棵树(集合)。
- 用数组
p[x]
来存放x
结点的父结点,即已知一个元素就可以访问其父结点,重复操作后即可访问这个元素所在的树的根节点。
图解:
补充:
如果p[x]
中的x
为树的根节点,那么他的根节点就是它本身即p[x] = x
。
代码实现:
int find(int x)
{
if (p[x] != x) return find(p[x]); // 如果不是树的根结点,那么继续查找
else return p[x]; // 是树的根结点,返回根节点
}
合并思路:
- 将两棵树的根结点相连,以其中一棵树的根结点作为相连后形成的树的根结点。(集合合并)
代码实现:
void join(int x, int y)
{
p[find(x)] = find(y); // 以y所在的树为根节点所合并成的树
}
查找方法优化:路径压缩
思想:
将树中的所有元素的父节点,全部置为树的根节点。(省去查找的时间)
代码实现:
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]); // 将父节点全部全部置为树的根节点
return p[x]; // 返回树的根节点
}