什么是并查集?
并查集是一种用来管理元素分组情况的数据结构。并查集可以高效地查询两个元素是否在同一个集合、合并两个不同的集合。
不过需要注意并查集虽然可以进行合并操作,但是却无法进行分割操作。
初始化
在初始化并查集时,每个元素都是单独的一个集合
for (int i = 0; i < n; i++) {
parent[i] = i;
}
查找
查找两个元素是否属于同一个集合就是查找两个元素是否在同一个树上,这里采用了路径压缩
public int find(int x) {
return parent[x] == x ? x : (parent[x] = find(parent[x]));
}
合并
我们将两个集合看作两个树,合并存在于两个树的元素时,将另一颗树的根连到另一个树上。
public void union(int x, int y) {
int parentX = find(x);
int parentY = find(y);
if (parentX != parentY) {
parent[parentX] = parentY;
}
}
合并时有可能会存在链路过长,我们可以用一个rank[]数组记录每个树的高度,然后将矮树联合到高树上。(按秩合并)
//按秩合并初始化
for (int i = 0; i < n; i++) {
parent[i] = i;
rank[i] = 0;
}
public void union2(int x, int y) {
int parentX = find(x);
int parentY = find(y);
if (parentX == parentY) {
return;
}
if (rank[parentX] < rank[parentY]) {
parent[parentX] = parentY
} else {
parent[parentY] = parentX;
if (rank[parentX] == rank[parentY]) {
rank[parentX]++;
}
}
}