JAVA数据结构之并查集【最终版】

用树实现的并查集

接口

public interface UF{
    int getSize();

    boolean isConnected(int p,int q);

    void unionElements(int p,int q);
}
public class UnionFindV6 implements UF{
    //孩子指向父亲
    private int[] parent;//parent[i] 表示的第i个元素指向的父节点
    private int[] rank;//sz[i]表示以i为根的集合中元素的个数


    /**
     * 构造函数
     */
    public UnionFindV6 (int size) {
        parent = new int[size];
        rank = new int[size];

        for (int i = 0; i < size; i++) {
            parent[i] = i;//初始的时候,每一个节点都指向它自己
            rank[i] = 1;
        }
    }

    @Override
    public int getSize() {
        return parent.length;
    }

    //查找过程,查找元素p所对应的的集合编号
    //O(h)复杂度,h为树的高度
    //这里用递归,需要返回值的 int
    //最后树只有两层
    private int find(int p) {

        if (p < 0 && p >= parent.length) {
            throw new IllegalArgumentException("p is out of bound");
        }
        //****路径压缩
        if (p != parent[p]) {//判断是否是根节点
        //直接挂接到根节点
            parent[p] = find(parent[p]);
        }
        return parent[p];
    } 


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

    @Override
    public void unionElements(int p, int q) {

        int pRoot = find(p);
        int qRoot = find(q);

        if (pRoot == qRoot) {
            return;
        }
        // 根据两个元素所在数的rank不同判断合并方向  【这里的rank指深度】
        // 将rank低的集合合并到rank高的集合上 
        if (rank[pRoot] < rank[qRoot]) {
            parent[pRoot] = qRoot;
        } else if (rank[pRoot] > rank[qRoot]) {
            parent[qRoot] = pRoot;
        } else {//rank[pRoot] == rank[qRoot]
            parent[qRoot] = pRoot;
            rank[pRoot] += 1;
        }

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章