参考: 《算法》第四版,p144 - p146
以leetcode, 200th : Number of Islands() 为例 (https://leetcode.com/problems/number-of-islands/)
对于加权quick-union算法,N个触点,在最坏情况下,find()、union()、isConnected()的成本增长数量级为lgN
package com.odyssey.app.algorithm.base;
/**
* 并查集算法 - 以lc200,number of islands 为例
*
* @author Dingsheng Huang
* @date 2020/3/29 16:15
*/
class UnionFind {
/**
* 连通分量,计数
*/
private int count;
/**
* 连通分量,标识
*/
private int[] id;
/**
* 加权,根节点对应连通分量的大小
*/
private int[] rank;
private void init(char[][] grid, int m, int n) {
for (int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
count++;
}
}
}
id = new int[m * n];
rank = new int[m * n];
for (int i = 0; i < m * n; i++) {
id[i] = i;
rank[i] = 1;
}
}
// 根节点一定是自旋的,即 p = id[p]
private int find(int p) {
while (p != id[p]) {
p = id[p];
}
return p;
}
private void union(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if (pRoot == qRoot) {
return;
}
if (rank[pRoot] > rank[qRoot]) {
id[qRoot] = pRoot;
rank[pRoot] += rank[qRoot];
} else {
id[pRoot] = qRoot;
rank[qRoot] += rank[pRoot];
}
count--;
}
private boolean isConnected(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
return pRoot == qRoot;
}
}