union-find算法改善(一)

在上一篇的union-find算法中,每次执行union()方法都要遍历一次数组,造成很大的时间消耗,那么,有没有一种方法来改善union()方法呢,提供一条思路。我们采用链式结构来存储数据,即属于一个分量的数据保存到一条链中中,比如1,3,5属于一条链,那么,我们把数组存储为a[1] = 3 a[3] =5 a[5] =5,这样可以减少union()将不用遍历数组,只用找到一个分量的根节点,再用根节点指向我们要绑定的数据,比如要绑定7,只需把a[5] = 7就可以了,合并两天链就生成了树结构,实现如下。

public class UF{
    private int[] a;
    private int count;
    //初始化
    public UF(int cap){
        count = cap;
        a = new int[cap];
        for(int i=0;i<cap;i++)
            a[i] = i;
    }
    //找到分量的标记
    public int find(int p){
        while(a[p]!=p) p = a[p];
        return p;
    }
    //连接p和q
    public void union(int p,int q){
        int rootP = find(p);
        a[rootP] = q;
        count--;
    }
    //返回分量的数量
    public int count(){
        return count;
    }
    //判断两个分量是否连通
    public boolean commected(int p,int q){
        return find(p)==find(q);
    }
}

这样用链式结构来存储触点在一般的情况下可以有效的提高效率,但也有特殊的情况,比如 0 1 0 2 03 04 ……在这种情况下我们union()时需要访问数组的次数为1,2,3,4,5…N这种情况是该算法执行的最坏情况,那么有没有一种方法来避免最坏情况的发生呢,再提供一个思路,使用一个辅助数组来记录每个分量的权。

猜你喜欢

转载自blog.csdn.net/qq_37520037/article/details/81588874