定义:
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的合并、查询)。
比如:我们可以用并查集来判断一个森林中有几棵树、某个节点是否属于某棵树等。
主要构成:
并查集主要由一个整型数组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,当两个值为一组织,则将其中一个作为根,将两下标的值相加,放在根下,另一下标对应的值变为根下标。