zoukankan      html  css  js  c++  java
  • 并查集 理解

    并查集

    第一次遇到并查集这个数据结构,发现这是一种很高效的算法,便打算纪录下来;

    当题目给定多条整数对,我们需要设计数据结构来保存已知的所有整数对的足够多的信息,并用它们来判断一对新对象是否是相连的;
    并查集就适用于这种动态连通性问题。

    union-find算法有这五种方法

    • UF
    • void union()
    • int find()
    • bool connected
    • int count

    代码实现

    class WeightUF {
    private:
        int * id; // 父链接数组(由触点索引的)
        int * sz;  // (由触点索引的)各个跟节点所对应的分量大小
        int * rank;
        int count;// 连通分量的数量
        
    public:
        WeightUF(int N) {
            count = N;
            id = new int[N];
            sz = new int[N];
            rank = new int[N];
            for (int i = 0; i < N; i++) {
                id[i] = i;
                rank[i] = 0;
                sz[i] = 1;
            }
        }
        
        ~WeightUF() {
            delete [] id;
            delete [] sz;
            delete [] rank;
        }
        
        // 跟随链接找到跟节点,在寻找跟节点时。对路径进行压缩,使整个树扁平化
        int find(int p) {
            while (p != id[p]) {
                // 将p节点的父节点设置为它的爷爷节点
                id[p] = id[id[p]];
                p = id[p];
            }
            return p;
        }
        
        int getCount() {
            return count;
        }
        
        bool connected(int p, int q) {
            return find(p) == find(q);
        }
        
        void connect(int p, int q) {
            int i = find(p);
            int j = find(q);
            if (i == j) return;
            // 将小树的跟结点连接到大树的跟结点上
            if (sz[i] < sz[j]) {
                id[i] = j; // 将一棵树(一个组)变成另外一棵树(即一个组)的子树
                sz[j] += sz[i];
            }
            else {
                id[j] = i;
                sz[i] += sz[j];
                if (sz[i] == sz[j])
    	            rank[i]++;
            }
            count--;
        }
        
    };
    
    

    上面的算法直接使用了路径压缩的加权quick-union(按秩合并)算法;
    比较quick-find和quick-union;

    quick-union是为了解决quick-find中union没输入一对数据都需要扫描整个id数组,虽然find只需要访问一次数组,但是归并需要平方级别的复杂程度;

    而weight quick-union则是为了解决随意的将一棵树连接到另一棵树上,于是记录每棵树的大小并总是将较小的树连接到较大的树上;


    性能比较

    算法 构造函数 union find
    quick-find算法 N N 1
    quick-union算法 N 树的高度 树的高度
    加权quick-union N logN logN
    使用路径压缩的加权quick-union N 接近1 接近1
    理想情况 N 1 1
  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/George1994/p/6346784.html
Copyright © 2011-2022 走看看