并查集

并查集是一种树型的数据结构,用于处理一些不交集(Disjoint Sets)的合并及查询问题

find

int find(int p) {
    return data[p];
}

另外一种实现,通过判断两个节点是否拥有同样的祖先来判断是否相连

while (p != parent[p]) {
    p = parent[p];
}
return p;

isConnected

boolean isConnected(int p, int q) {
    return find(p) == find(q);
}

union

int pid = find(p);
int qid = find(q);
if (pid == qid){
    return;
}
for (int i = 0; i < count; i++) {
    if (data[i]==pid){
        data[i]=qid;
    }
}

使用另外一种实现的union

int qRoot = find(p);
int pRoot = find(q);
if (qRoot == pRoot){
    return;
}
parent[pRoot]=qRoot;

基于size的优化,维护一个size数组,代表以i为根的集合的元素个数

if (sz[pRoot]<sz[qRoot]){        
    parent[pRoot] = qRoot;
    sz[qRoot]+=sz[pRoot];
}else {
    parent[qRoot] = pRoot;
    sz[qRoot]+=sz[pRoot];
}

使用rank来决定谁连接谁

if (rank[pRoot] < rank[qRoot]) {
    parent[pRoot] = qRoot;
} else if ((rank[pRoot] > rank[qRoot])) {
    parent[qRoot] = pRoot;
} else {
    parent[pRoot] = qRoot;
    rank[qRoot] += 1;
}

路径压缩

while (p != parent[p]) {
    parent[p]=parent[parent[p]];
    p = parent[p];
}
return p;