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;
        }

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