• 并查集


    并查集是集合的一种,它只有两种方法,合并和查找。

    合并就是把两个元素所在的集合合并为一个。

    查找就是查找某元素所属的集合。

    一般并查集用树的父指针数组来存储实现。根节点数组值为负数,负几表示该集合有几个元素。

    元素和集合名称对应数组索引。从属关系对应相应数组值。数组值为负数,表示对应索引为树的根,也就是集合名。

    初始状态下所有元素都是一颗单独的树,也就是说所有数组值都初始化为-1.

    某种意义上并查集的数组实现也可看成一种散列。

    由于并查集只有两种操作,所以重要的不是元素之间的父子关系,而是元素的从属关系。

    所以最优并查树的深度应为2。一般优化并查树,也是往这个方向优化。

    并查树合并O(1), 查找O(logn)。

    并查集是划分等价类的最佳选择。

    下面给出代码实现:

    package com.company;
    
    /**
     * UnionFindSet is a set to tackle only Union and Find operations in set.
     * Created by qiguo on 2017/3/21.
     */
    public class MyUnionFindSet {
        private int[] array;
        private int storageSize;
        public MyUnionFindSet(){
            this.storageSize = 10;
            this.array = new int[this.storageSize];
            for (int i = 0; i < this.storageSize; i++) {
                array[i] = -1;
            }
        }
    
        /**
         * merge two element into one set
         * @param s1 element s1
         * @param s2 element s2
         * @return union set element num
         */
        public int union(int s1, int s2){
            int set1 = find(s1);
            int set2 = find(s2);
            if (set1 == set2){
                return -1;
            }
            if (array[set1] <= array[set2]){
                array[set1] += array[set2];
                array[set2] = set1;
                return array[set1];
            }else {
                array[set2] += array[set1];
                array[set1] = set2;
                return array[set2];
            }
        }
    
        /**
         * find the set that element belongs to
         * @param element
         * @return set number
         */
        public int find(int element){
            int tmp = element;
            while (array[tmp] > 0){
                tmp = array[tmp];
            }
            return tmp;
        }
    
        /**
         * collapse the branch while find, to optimize the structure of the tree.
         * @param element
         * @return the set number that element belongs to
         */
        public int collapsingFind(int element){
            int tmp = element;
            while (array[tmp] > 0){
                tmp = array[tmp];
            }
            while (array[element] > 0){
                int parent = array[element];
                array[element] = tmp;
                element = parent;
            }
            return tmp;
        }
    
        public void print(){
            for (int element: array) {
                System.out.printf(element + " ");
            }
            System.out.println();
        }
        public static void main(String[] args){
            MyUnionFindSet myUnionFindSet = new MyUnionFindSet();
            myUnionFindSet.union(1,2);
            myUnionFindSet.union(2,3);
            myUnionFindSet.union(1,5);
            myUnionFindSet.union(4,6);
            myUnionFindSet.union(7,9);
            myUnionFindSet.union(1,6);
            myUnionFindSet.union(1,6);
            myUnionFindSet.print();
            myUnionFindSet.collapsingFind(6);
            myUnionFindSet.print();
            System.out.println(myUnionFindSet.find(6));
            System.out.println(myUnionFindSet.find(1));
        }
    
    
    }
    

      

  • 相关阅读:
    Codeforces 934 B.A Prosperous Lot
    Codeforces 934 A.Compatible Pair
    UVA 12898
    Codeforces Round #376 (Div. 2) C. Socks bfs
    Codeforces Round #377 (Div. 2) C. Sanatorium 水题
    Codeforces Round #377 (Div. 2) D. Exams 二分
    Codeforces Beta Round #91 (Div. 1 Only) E. Lucky Array 分块
    hdu 5154 Harry and Magical Computer 拓扑排序
    Codeforces Round #272 (Div. 2) C. Dreamoon and Sums 数学
    Codeforces Round #288 (Div. 2) C. Anya and Ghosts 模拟
  • 原文地址:https://www.cnblogs.com/zqiguoshang/p/6593245.html
Copyright © 2020-2023  润新知