1. 程式人生 > >並查集(Java實現)

並查集(Java實現)

... oid 打印數組 == 集合 nbsp fin [] 數組

並查集:用數組實現

思路

數組裏存的數字代表所屬的集合。比如arr[4]==1;代表4是第一組。如果arr[7]==1,代表7也是第一組。既然 arr[4] == arr[7] == 1 ,那麽說明4 和 7同屬於一個集合,

代碼

/**
 * 數組實現並查集,元素內數字代表集合號
 */
public class UnionFind {
    /**
     * 數組,表示並查集所有元素
     */
    private int[] id;

    /**
     * 並查集的元素個數
     */
    private int size;

    /**
     * 構造一個新的並查集
     *
     * @param size 初始大小
     */
    public UnionFind(int size) {
        //初始化個數
        this.size = size;
        //初始化數組,每個並查集都指向自己
        id = new int[size];
        for (int i = 0; i < size; i++) {
            id[i] = i;
        }
    }

    /**
     * 查看元素所屬於哪個集合
     *
     * @param element 要查看的元素
     * @return element元素所在的集合
     */
    private int find(int element) {
        return id[element];
    }

    /**
     * 判斷兩個元素是否同屬於一個集合
     *
     * @param firstElement  第一個元素
     * @param secondElement 第二個元素
     * @return <code>boolean</code> 如果是則返回true。
     */
    public boolean isConnected(int firstElement, int secondElement) {
        return find(firstElement) == find(secondElement);
    }

    /**
     * 合並兩個元素所在的集合,也就是連接兩個元素
     *
     * @param firstElement  第一個元素
     * @param secondElement 第二個元素
     */
    public void unionElements(int firstElement, int secondElement) {
        //找出firstElement所在的集合
        int firstUnion = find(firstElement);
        //找出secondElement所在的集合
        int secondUnion = find(secondElement);

        //如果這兩個不是同一個集合,那麽合並。
        if (firstUnion != secondUnion) {
            //遍歷數組,使原來的firstUnion、secondUnion合並為secondUnion
            for (int i = 0; i < this.size; i++) {
                if (id[i] == firstUnion) {
                    id[i] = secondUnion;
                }
            }
        }
    }

    /**
     * 本並查集使用數組實現,為了更直觀地看清內部數據,采用打印數組
     */
    private void printArr() {
        for (int id : this.id) {
            System.out.print(id + "\t");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int n = 10;
        UnionFind union = new UnionFind(n);
        System.out.println("初始:");
        union.printArr();

        System.out.println("連接了5 6");
        union.unionElements(5, 6);
        union.printArr();

        System.out.println("連接了1 2");
        union.unionElements(1, 2);
        union.printArr();

        System.out.println("連接了2 3");
        union.unionElements(2, 3);
        union.printArr();

        System.out.println("連接了1 4");
        union.unionElements(1, 4);
        union.printArr();

        System.out.println("連接了1 6");
        union.unionElements(1, 6);
        union.printArr();

        System.out.println("1  5 是否連接:" + union.isConnected(1, 5));

        System.out.println("1  8 是否連接:" + union.isConnected(1, 8));
    }
}

並查集:借助樹形結構

待續....

並查集優化:路徑壓縮

待續....

並查集(Java實現)