并查集三种Java代码实现

@代码模板

package Algorithm;

public class UF {
    private int[] id;//连通分量的id
    private int count;
    public UF(int n){//初始化n个触点
        count=n;
        id=new int[n];
        for (int i = 0; i < n; i++) {
            id[i]=i;//初始化时,每个触点都是一个单独的分量
        }
    }
    public int getCount(){//得到分量数
        return count;
    }
    public boolean connected(int p,int q){//判断触点p,q是否连通
        return find(q)==find(p);
    }
    public int find(int p){//找到触点p所在的分量id
    }
    public void union(int p,int q){//合并触点p,q
    }
}

实现find和union即可。

1.用循环将一个分量中的触点全部改变

public int find(int p){
        return id[p];
    }
    public void union(int p,int q){
        int pID=find(p);
        int qID=find(q);
        if(pID==qID) return;
        for (int i = 0; i < id.length; i++) {
            if(id[i]==pID) id[i]=qID;
        }
        count--;
    }

2. 链接法

  public int find(int p){
       while (p!=id[p]) p=id[p];
       return p;
    }
    public void union(int p,int q){
        int pID=find(p);
        int qID=find(q);
        if(pID==qID) return;
        id[pID]=qID;
        count--;
    }

就两个分量,id=[1, 1, 1, 8, 3, 0, 5, 1, 8, 8]。比如下标4的是3,那么说明下标4链接到下标3,在8这个分量里面。

3. 加权树

private int[] sz;//保存树的高度,初始化都为1   
public int find(int p){
       while (p!=id[p]) p=id[p];
       return p;
    }
    public void union(int p,int q){
        int pID=find(p);
        int qID=find(q);
        if(pID==qID) return;
        if(sz[pID]<sz[qID]){//小树加到大树上面
            sz[qID]+=sz[pID];
            id[pID]=qID;
        }else{
            sz[pID]+=sz[qID];
            id[qID]=pID;
        }
        count--;
    }

路径压缩

private int find(int p){
	if(p==id[p]) return p;
	return id[p]=find(id[p]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值