动态联通
基础类
class UF{
constructor(n){
this.count=n;
this.id=[];
for(let i=0;i<n;i++){
this.id[i]=i;
}
}
count(){
return this.count;
}
connected(p,q){
return this.find(p)==this.find(q);
}
}
UF.prototype.find=find;
UF.prototype.union=union;
quick-find
当且仅当id[p]==id[q]时,p与q为联通的。即若p与q已经存在于一个联通分量,则不需采用一个其他方法。若不是,则将id[p]和id[q]的所有联通分量的变成相同的联通分量。
时间复杂度,find,union:o(N)
function find(p){
return this.id[p];
}
function union(p,q){
if(this.connected(p,q)){
return;
}else{
let index;
var temp=this.id[q];
while((index=this.id.indexOf(temp,index+1))>=0){
this.id[index]=this.id[p];
this.count--;
}
return;
}
}
时间复杂度为:O(n^2)
quick-union
定义:每一个触点对应的id[]元素都是同一个分量中,另一个触点的名称。
时间复杂度:union树高,find 树高
最坏情况为平方级
/*quick-union*/
function find(p){
//求根节点
while(p != this.id[p]){
p=this.id[p];
}
return p;
}
function union(p,q){
let pRoot=this.find(p);
let qRoot=this.find(q);
if(pRoot==qRoot){
return;
}else{
this.id[qRoot]=pRoot;;
}
this.count--;
}
加权quick-union算法
改进:将小树连接到大树上,降低算法复杂度(算法4按树的大小连接,本文按树的高度进行连接)
union复杂度lgN,find复杂度 lgN
class UF{
constructor(n){
this.count=n;
this.id=[];
this.size=[];
for(let i=0;i<n;i++){
this.id[i]=i;
this.size[i]=1;
}
}
count(){
return this.count;
}
connected(p,q){
return this.find(p)==this.find(q);
}
}
UF.prototype.find=find;
UF.prototype.union=union;
function find(p){//寻找根节点
//求根节点
while(p != this.id[p]){
p=this.id[p];
}
return p;
}
function union(p,q){
let pRoot=this.find(p);
let qRoot=this.find(q);
if(pRoot==qRoot){
return;
}else{
if(this.size[pRoot]==this.size[qRoot]){
this.size[pRoot]++;
this.id[qRoot]=pRoot;
}else if(this.size[pRoot]>this.size[qRoot]){
this.id[qRoot]=pRoot;
}else{
this.id[qRoot]=pRoot;
}
}
this.count--;
}