并查集的理解

Posted 黑桃_K_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集的理解相关的知识,希望对你有一定的参考价值。

定义:

并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的合并、查询)。
比如:我们可以用并查集来判断一个森林中有几棵树、某个节点是否属于某棵树等。

主要构成:

并查集主要由一个整型数组pre[ ]和两个函数:查找函数(findIndex)、**合并函(unionNum)**构成。
数组 _ufs[ ] 记录了每个点的前驱节点是谁,函数 findIndex(x) 用于查找指定节点 x 属于哪个集合,函数 unionNum(x1,x2) 用于合并两个节点 x1 和 x2 。

作用:

并查集的主要作用是求连通分支数(如果一个图中所有点都存在可达关系(直接或间接相连),则此图的连通分支数为1;如果此图有两大子图各自全部可达,则此图的连通分支数为2……)

代码及解析:

class UnionFindSet 
public:
//初始化一个数组,并且数组的每个值都是-1,表示当前组只有一个元素并且,没有父节点
    UnionFindSet(int n) 
        _ufs.resize(n, -1);
    

//查找节点x的最上层的根节点的下标值
    int findIndex(int x) 
        assert(x < _ufs.size());

        while (_ufs[x] >= 0)
            x = _ufs[x];
        return x;
    
    
 //	x1 下标和 x2 下标合并
 //1.首先判断安全
 //2.查找到当前下标对应的跟节点的下标值
 //3.将x2根节点下标的值—(即为-n)与x1对应根节点的下标的值相加,赋值给x1的下标对应根节点的值,表示当前组织关系共有多少个 
 //4.将x2根节点的下标值变为x1的下标

    void unionNum(int x1, int x2) 
        assert(x1 < _ufs.size());
        assert(x2 < _ufs.size());
        int root1 = findIndex(x1);
        int root2 = findIndex(x2);
        if (root1 != root2) 
            _ufs[root1] += _ufs[root2];
            _ufs[root2] = root1;
        
    
//返回共有多少个组织
    int setSize() 
        int size = 0;
        for (int i = 0; i < _ufs.size(); ++i) 
            if (_ufs[i] < 0)
                ++size;
        
        return size;
    
private:
    vector<int> _ufs;
;

0 1 2 3 4 5 6 7 8

-1 -1 -1 -1 -1 -1 -1 -1 -1

下标对应值初始化为-1,当两个值为一组织,则将其中一个作为根,将两下标的值相加,放在根下,另一下标对应的值变为根下标。

以上是关于并查集的理解的主要内容,如果未能解决你的问题,请参考以下文章

并查集的理解

并查集的理解

S - Cyclic Components (并查集的理解)

并查集的基础

并查集(入门)

并查集的小节