算法——Union-find算法(并查集)

1. 动态连通性

引出问题:问题的输入是一个整数对,其中每个整数都表示一个某种类型的对象,一对整数p、q可以理解为“p q是相连的”。我们假设“相连”是一种等价关系,这也意味着它具有:

  • 自反性:p和q是互连的;
  • 对称性:如果p、q是相连的,那么p、q也是相连的;
  • 传递性:如果p和q是相连的且q和r是相连的,那么q和r也是相连的。

等价关系能够将对象分为多个等价类。在这里,当且仅当两个对象相连时他们才属于同一个等价类。我们需要设计一个数据结构来保存程序已知的所有整数对的足够多的信息,并用他们来判断一对新对象是否是互联的。我们将这个问题通俗的叫做动态连通性问题。以下举一些常见的列子:

1.1 网络

     大型计算机的连接数

1.2 变量名等价性

1.3 数学集合

 

2 实现

2.1 quick-find算法:

public class UF {
    private int[] 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 this.count;
    }
    public boolean connected(int q,int p) {
                return find(q)==find(p);
    }
    public int find(int q){

        //return id[q];
    }
    public void union(int q,int p) {
        // TO do
    

    }
} 

    算法实现经历了 从quick-find 到quick-union再到加权的quick-union的改进,这里给出最终的实现算法:

public class WeightQuickUnionUF {
    private int[] id;
    private int[] sz;
    private int count;
    public WeightQuickUnionUF(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] = i;
        }

    }
    public int count() {

        return count;
    }
    public boolean connected(int q,int p) {
        return find(q) == find(p);
    }
    public int find(int q) {
        while(q != id[q]) {
            q = id[q];
        }
        return q;
    }
    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--;
    }



}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值