什么是并查集,就是一种方便快速查找是否连通的一种算法。
用途:查看某2点是否连通(十分便捷),以及路径问题(这个复杂点).leetcode 200题岛屿个数
转载一个什么便于理解的博客:
博客
主要问题是路径压缩算法:
1.
int son,tep;
son = p;
while(p!= parent[p])
p = parent[p]; // p已经等于root
while(son != p) // 路径压缩的while 循环
{ // 保留son父节点
tep = parent[son];
// 压缩当前节点直接到根节点
parent[son] = p;
// son赋值给上一级节点,开始压缩上一级节点
son = tep;
}
2.bobo 老师
private int find(int p) throws Exception {
if(p <0 || p> parent.length-1)
throw new Exception(" out of bound");
while(p != parent[p]) {
parent[p] = parent[parent[p]]; //路径压缩
p = parent[p];
}
return p;
}
demo:
package com.hnist.lzn.UnionFind;
public class UnionFind5 implements UF {
private int[] parent; // 父节点数组
private int[] rank; // 当前深度数组
public UnionFind5(int size){
parent = new int[size];
rank = new int[size];
for(int i = 0; i< parent.length;i++) {
parent[i] = i;
rank[i] = 1;
}
}
@Override
public int size() {
return parent.length;
}
// O(h)h是树高 ,find方法用来确定元素属于哪个子集
private int find(int p) throws Exception {
if(p <0 || p> parent.length-1)
throw new Exception(" out of bound");
while(p != parent[p]) {
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
// O(h) 这个方法判断p,q是否属于同一集合,解决了用途1
@Override
public boolean isConnected(int p, int q) throws Exception {
return find(p) == find(q);
}
// O(h) h是树高 unoin方法,将2个子集合并成一个集合
@Override
public void unoin(int p, int q) throws Exception {
int proot = find(p);
int qroot = find(q);
if(proot == qroot)
return;
if(rank[proot] > rank[qroot])
{
parent[proot] = qroot;
}
else if(rank[proot] < rank[qroot]){
parent[qroot] = proot;
}else{
parent[proot] = qroot;
rank[qroot] += 1;
}
}
}