/**
*【路径压缩】处理并查集中的深的结点
* 对find方法进行优化
* 路径压缩中时间复杂度近乎为O(1)
*就是让当前结点指向自己父亲的父亲,减少深度
*非递归的路径压缩
*路径压缩也可以采用基于集合中元素的个数而非深度来
*/
public class UnionFind5 {
private int count;
private int[] parent;
private int[] rank;
public UnionFind5(int n) {
count=n;
parent=new int[n];
rank=new int[n];
for(int i=0;i<count;i++) {
parent[i]=i;
rank[i]=1;
}
}
public boolean isConnected(int p,int q) {
return find(p)==find(q);
}
int find(int p) {
while(p!=parent[p]) {
//路径压缩,让当前结点指向自己父亲的父亲
parent[p]=parent[parent[p]];
p=parent[p];
}
return p;
}
public void union(int p,int q) {
int pRoot=find(p);
int qRoot=find(q);
if(pRoot==qRoot)
return;
if(rank[pRoot]>rank[qRoot]) {
parent[qRoot]=pRoot;
}else if(rank[pRoot]<rank[qRoot]) {
parent[pRoot]=qRoot;
}else {
parent[qRoot]=pRoot;
rank[pRoot]+=1;
}
}
//测试数组
public void printParent() {
for(int a:parent)
System.out.print(a+" ");
System.out.println();
}
}
/**
* 递归的路径压缩
* 时间要比非递归的慢
*/
public class UnionFind6 {
private int count;
private int[] parent;
private int[] rank;
public UnionFind6(int n) {
count=n;
parent=new int[n];
rank=new int[n];
for(int i=0;i<count;i++) {
parent[i]=i;
rank[i]=1;
}
}
public boolean isConnected(int p,int q) {
return find(p)==find(q);
}
int find(int p) {
if(p!=parent[p])
parent[p]=find(parent[p]);
return parent[p];
}
public void union(int p,int q) {
int pRoot=find(p);
int qRoot=find(q);
if(pRoot==qRoot)
return;
if(rank[pRoot]>rank[qRoot]) {
parent[qRoot]=pRoot;
}else if(rank[pRoot]<rank[qRoot]) {
parent[pRoot]=qRoot;
}else {
parent[qRoot]=pRoot;
rank[pRoot]+=1;
}
}
//测试数组
public void printParent() {
for(int a:parent)
System.out.print(a+" ");
System.out.println();
}
}