算法:动态连通性问题

本文介绍了动态连通问题的不同算法实现,包括快速查找法、快速合并法及其改进版。通过对比不同方法的特点,展示了如何逐步优化算法以提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在《算法》书中看到动态连通问题,今天给出其实现的代码。

接口

package com.chapter1;

public interface UnionFind {

    int getCount();

    boolean isConnected(int p,int q);

    int find(int p);

    void union(int p,int q);

}

抽象类

package com.chapter1;

public abstract class AbstractUnionFind implements UnionFind {
    protected int[] ids;//分量id
    protected int count;//分量数量

    public AbstractUnionFind(int n){
        count = n;
        ids = new int[n];
        for(int i=0;i<n;i++){
            ids[i] = i;
        }
    }

    public int getCount() {
        return count;
    }

    public boolean isConnected(int p, int q) {
        return find(p)==find(q);
    }

    public void printlnDetail(){
        for(int i=0;i<ids.length;i++){
            System.out.println(ids[i]);
        }
    }
}

Quick-find实现

package com.chapter1;

public class UnionQuickFind extends AbstractUnionFind{


    public UnionQuickFind(int n){
        super(n);
    }

    public int find(int p){
        return ids[p];
    }

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

quick-union版本

package com.chapter1;

public class QuickUnionFind extends AbstractUnionFind{

    public QuickUnionFind(int n){
        super(n);
    }
    public int find(int p) {
        while(p!=ids[p]){
            p = ids[p];
        }
        return p;
    }
    public void union(int p, int q) {
        int idP = find(p);
        int idQ = find(q);
        if(idP == idQ) {
            return;
        }
        ids[idP] = idQ;
        count--;
    }
}

压缩的quick-union版本

package com.chapter1;

public class CompressQuickUnionFind extends QuickUnionFind {

    public CompressQuickUnionFind(int n) {
        super(n);
    }

    public int find(int p) {
        int cur = p,next;
        while(p != ids[p]){
            p = ids[p];
        }
        while(ids[cur] != p) {
            next = ids[cur];
            ids[cur] = p;
            cur = next;
        }
        return p;
    }
}

带权重的quick-union

package com.chapter1;

public class WeightedQuickUnionFind extends QuickUnionFind {

    private int[] sz;
    WeightedQuickUnionFind(int n){
        super(n);
        sz = new int[n];
        for(int i=0;i<n;i++){
            sz[i] = 1;
        }
    }

    @Override
    public void union(int p,int q){
        int idP = find(p);
        int idQ = find(q);
        if(idP == idQ) return;

        if(sz[idP] < sz[idQ]){
            ids[idP] = idQ;
            sz[idQ] += sz[idP];
        }else{
            ids[idQ] = idP;
            sz[idP] += sz[idQ];
        }
        count--;
    }
}

压缩并带权重的quick-union

package com.chapter1;

public class CompressWeightedQuickUnionFind extends WeightedQuickUnionFind{

    CompressWeightedQuickUnionFind(int n){
        super(n);
    }

    @Override
    public int find(int p){
        int cur = p,next;
        while(p != ids[p]){
            p = ids[p];
        }
        while(ids[cur] != p) {
            next = ids[cur];
            ids[cur] = p;
            cur = next;
        }
        return p;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值