1 定义:
并查集是一种用来管理元素分组情况的数据结构,用于处理一些 不相交 集合的合并及查询问题。其精妙之处在于用树来表示集合。并规定每棵树的根节点就是这棵树所对应的集合的代表元。
2 并查集可高效地进行如下操作: (并查集虽然可以进行合并,但无法进行分割)
(1)查询元素a和元素b是否属于同一组。
(2)合并元素a和元素b所在的组。
3 操作步骤:
(1)初始化:把每个点所在集合初始化为其自身。
(2)查找:查找元素所在的集合,即根节点。
(3)合并:将两个元素所在的集合合并为一个集合。合并之前,应先判断两个元素是否属于同一集合。
4 注意:
在特殊情况下,这棵树可能是一条很长的链,使得效率很低。
改进方法: 通过路径压缩, 在“查找”时,将遍历过的结点都改为树根的儿子。
5 并查集的实现:
#include<stdio.h>
#define MAX_N 100
int par[MAX_N]; //父亲
int rank[MAX_N]; //树的高度
//初始化n个元素
void init(int n)
{
for (int i = 0; i < n; i++)
{
par[i] = i;
rank[i] = 0;
}
}
//查询树的根
int find(int x)
{
if (par[x] == x)
{
return x;
}
else
{
return par[x] = find(par[x]);
}
}
//合并x 和 y所属的集合
void unite(int x, int y)
{
x = find(x);
y = find(y);
if (x == y)
return;
if (rank[x] < rank[y])
{
par[x] = y;
}
else
{
par[y] = x;
if (rank[x] == rank[y])
rank[x]++;
}
}
//判断x 和 y是否属于同一个集合
bool same(int x, int y)
{
return find(x) == find(y);
}