并查集定义:主要是2个核心操作,合并2个元素到一个集合,查询任意集合的所在元素的祖宗。应用在图连接分量的判断。
实现类
public class UnionFind {
private int[] parent; // 标注当前元素的父节点的位置
private int[] rank; // 标注当前元素的层级数
private int size; // 并查集中的元素个数
public UnionFind (int size){
this.size = size;
parent = new int[size];
rank = new int[size];
init();
}
private void init() {
for (int i = 0; i < size; i++) {
// 初始化时所有的节点的父节点指向本身,所有的元素层级均为 1
parent[i] = i;
rank[i] = 1;
}
}
/**
* 寻找当前节点的根节点元素
* @param target
* @return
*/
public int find(int target) {
if(target >= size)
throw new ArrayIndexOutOfBoundsException();
if(target == parent[target])
return target;
return find(parent[target]);
}
/**
* 连接两个元素
* @param p
* @param q
*/
public void union(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if(pRoot == qRoot)
return;
if(rank[pRoot] > rank[qRoot]) { // p 所在的树的高度比 q 所在输的高度高,这时应该让 q 的根节点元素连接到 p 的根节点元素
parent[qRoot] = pRoot; // 此时树的高度不变
} else if(rank[pRoot] < rank[qRoot]) {
parent[pRoot] = qRoot; // 此时树的高度不变
} else {
parent[pRoot] = qRoot; // 此时树的高度 +1
rank[qRoot] += 1;
}
}
/**
* 判断两个节点是否连接
* @param p
* @param q
* @return
*/
public boolean isConnected(int p, int q) {
// 如果两个节点的根节点一致则表示这两个节点是相连接的
return find(p) == find(q);
}
}
测试类
public static void main(String[] args) {
int size = 10;
// Step 1: init()
UnionFind uf = new UnionFind(size);
// Step 2: union()
uf.union(1,2);
uf.union(3,4);
uf.union(0,9);
uf.union(4,7);
uf.union(6,5);
uf.union(5,8);
uf.union(3,9);
uf.union(1,8);
// Step 3: find()
System.out.println(uf.find(0)); // 9
System.out.println(uf.find(1)); // 5
System.out.println(uf.find(2)); // 5
System.out.println(uf.find(3)); // 9
System.out.println(uf.find(4)); // 9
System.out.println(uf.find(5)); // 5
System.out.println(uf.find(6)); // 5
System.out.println(uf.find(7)); // 9
System.out.println(uf.find(8)); // 5
System.out.println(uf.find(9)); // 9
// Step 4: isConnected
System.out.println(uf.isConnected(0,1)); // false
System.out.println(uf.isConnected(1,2)); // true
System.out.println(uf.isConnected(3,4)); // true
System.out.println(uf.isConnected(5,6)); // true
System.out.println(uf.isConnected(7,8)); // false
System.out.println(uf.isConnected(8,9)); // false
System.out.println(uf.isConnected(2,4)); // false
System.out.println(uf.isConnected(3,5)); // false
System.out.println(uf.isConnected(5,6)); // true
System.out.println(uf.isConnected(7,9)); // true
}
本文来自 小平_ 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/xiaoping0915/article/details/79727603?utm_source=copy