对并查集的一个直观理解





- 并查集初始化 ```java int N = 100; // N 为初始集合的个数 int[] parent = new int[N];
for(int i = 0; i < N; i++){
parent[i] = i;
}
2. find 函数```java// 最原始版本int find(int x) {if(parent[x] == x){ // 找到根节点了(类似于上面例子的帮派大佬)return x;}else {return find(parent[x]);}}// 路径压缩// 在递归找根节点的过程中,将这一过程中遍历到的非根结点的父节点直接指向为根结点// 使得每个元素到根节点的路径尽可能的短int find(int x){if(parent[x] == x){return x;}else{parent[x] = find(parent[x]);return parent[x];}}// 上述代码还可以进行简写int find(int x) {return parent[x] == x ? x : (parent[x] = find(parent[x]));}
- union 函数 ```java // 最原始版本 void merge(int i, int j) { parent[find(i)] = find(j); }
// 按秩合并(秩可以理解为根节点的深度,对于非根节点而言,秩可能并没有表示深度) // 我们需要在初始化时,对rank[] 进行初始化 void init(int n){ for(int i = 0; i < n; i++){ //省略对parent的初始化
rank[i] = i;
}
}
void merge(int i, int j) { int x = find(i); int y = find(j);
// 秩小的合并到秩大的树中
// 此处为什么不先判断 x,y 是否相等?
// 因为如果 x,y相等,下面的if-else 代码块仍然不会改变二者的parent
if(rank[x] <= rank[y]){
parent[x] = y;
}else {
parent[y] = x;
}
if(rank[x] == rank[y] && x != y){
rank[y]++;
}
}
```
