并查集,是一个集合,主要为了实现了合并和查找两个功能
根据不同的题目需求进行使用
Union and Find Set (UFSet)
结构抽象: 树形结构
一般做题类型: 等价类
但是为了确保并查集的退化,所以,在进行合并的时候不像一般的集合合并一样。
本质上是数组(线段树,如果你熟悉树的结构的话)
当数值为 负数的时候,表示这是一个根(其绝对值大小,表示的是对应树形下的 节点数目,包括自己)
否者就是指向的parent对应的index
查找函数:
int find(int x){
if (x < 0) return -1;
while (parent[x] > 0) x = parent[x];
return x;
}
一般的合并函数:
void Union(int root1, int root2){
parent[root1] += parent[root2];
parent[root2] = root1;
}
但很显然,如果这样子不断地合并,很有可能会出现变成一条直线的退化(大大提高树形结构的层数)。
所以有一种改良方法:
就是说,每次都是将对应的树的根节点进行比较,将小树作为第一个层的孩子,粘附在大树的上。这样就可以避免树形结构层数过高的问题
void weightUnion(int root1, int root2){
int p1 = find(root1), p2 = find(root2);
int temp;
if (p1 != p2) {
temp = parent[p1] + parent[p2];
if (parent[p1] < parent[p2]){
parent[p2] = p1;
parent[p1] = temp;
} else {
parent[p1] = p2;
parent[p2] = temp;
}
}
}