动态连通性
定义
对于解决大型问题中,比如网络,(计算机)都有很大的作用。
union-find
public class quick_find{
private int count;
private int[] id;
quick_find(int n){
count=n;
id=new int[count];//
for(int i=0;i<n;i++)
{
id[i]=i;
}
}
public int count(){
return count;
}
public boolean connected(int p,int q){
return find(p)==find(q);
}
private int find(int p){
return id[p];
}
public void quick(int p,int q){
int pID=find(p);
int qID=find(q);
if(qID==pID) return;
for(int i=0;i<id.length;i++)
if(id[i]==pID) id[i]=qID;
count--;
}
}
quick-union
看成森林,有森林构造树。
public class quick_union {
private int count;
private int[] id;
quick_union(int n){
count=n;
id=new int[count];
for(int i=0;i<n;i++)
{
id[i]=i;
}
}
public int count(){
return count;
}
public boolean connected(int p,int q){
return find(p)==find(q);
}
private int find(int p){
while(p!=id[p])p=id[p];
return p;
}
public void union(int p,int q){
int qroot=find(q);
int proot=find(p);
if(proot==qroot) return;
id[proot]=qroot;
count--;
}
}
加权的quick-union
将每个节点看作权值为1的树。用sz[]来表示。总是将小树挂在大树身上,能够减少复杂度。
(能够用于大规模的连通性问题)较优。
public class WeightQuickunion {//加权quick-union
private int count;
private int[] id;
int sz[];
WeightQuickunion(int n){
count=n;
id=new int[count];
sz=new int[count];
for(int i=0;i<n;i++)
{
id[i]=i;
sz[i]=1;
}
}
public int count(){
return count;
}
public boolean connected(int p,int q){
return find(p)==find(q);
}
private int find(int p){
while(p!=id[p])p=id[p];
return p;
}
public void union(int p,int q){
int qroot=find(q);
int proot=find(p);
if(proot==qroot) return;
if(sz[qroot]<sz[proot]){
id[qroot]=proot;
sz[proot]+=sz[proot];
}
else{
id[proot]=id[qroot];
sz[qroot]+=sz[qroot];
}
count--;
}
}
性能特征
后续还有路径压缩的加权quick-union算法(最右的算法)。