union-find算法

这篇博客介绍了Quick-Union算法在判断两个触点是否属于同一连通分量中的应用。作者详细讲解了Quick-Find、Quick-Union以及加权Quick-Union三种算法的实现,重点在于优化查找和合并操作的时间复杂度,以提高算法效率。通过实例展示了如何使用这些算法来维护并查集,并分析了不同版本算法的性能特点。
摘要由CSDN通过智能技术生成


判断两个触点是否存在于相同的连通分量中?

quick-find算法

public class UF{
    private int[] id;  //分量id
    private int count; //分量数量
    public UF(int N){
        count = N;
        id = new int[N];
        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);}
    
    //==========================quickfind算法,时间复杂度是N2级别的
    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;  //如果pID == qID ,那么说明两个触点已经相连接,直接跳过循环
        for (int i = 0 ; i < id.length , i++){
            if(id[i] == pID) id[i] = qID;
        }
        count--;
    }
    //==========================quickunion算法,使得union方法的复杂度总是线性级别的
    public int find(int p){
        while(p != id[p]) p = id[p];//找出分量的名称,也就是说找到p = id[p] 的源头,就是连通的源头,使得每一个数都能找到最终的那个数,看两者是否相等。
        return p;
    }
    public void union(int p , int q){
        int pRoot = find(p);
        int qRoot = find(q);
        if (pRoot == qRoot) return;
        id[pRoot] = qRoot;
        count--;
    }
    //=========================加权quickunion算法
    //增加额外的数组
    private int[] sz; //各个根节点所对应的分量的大小
    //重写有参构造方法
    public UF(int N){
        count = N;
        id = new int[N];
        for(int i = 0;i< N; i++){
            id[i] = i;
        }
        sz = new int[N];
        for(int i = 0;i< N;i++) sz[i] = 1 ;
    }
    public int find(int p){
        while(p != id[p]) p = id[p];//找出分量的名称,也就是说找到p = id[p] 的源头,就是连通的源头
        return p;
    }
    //下面的union方法使得对某个数找到其根触点的次数变少,也就是访问数组的次数减少
    public void union(int p , int q){
        int i = find[p];
        int j = find[q];
        if ( i == j ) return;
        if (sz[i] < sz[j]) {id[i] = j ; sz[j] += sz[i]}
        else               {id[j] = i ; sz[i] += sz[j]}
        count--;  
    }    
    
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值