class unionFindSet
{
private:
vector<int> parent;
public:
unionFindSet(int eleNums) // 构造函数
{
parent.resize(eleNums + 1, 0); //用零做初始化,代表刚开始所有元素各自都是一个集合,同时零表示该集合的秩;
} //不使用索引为0的元素,因为合并使用了秩合并
int setFind(int index) //查找操作,查找的同时进行路径压缩,完全压缩
{
if (parent[index] <= 0) // 小于等于零的元素都是根节点,其值代表该集合的秩;不是根节点的元素,其值表示其父节点的索引
return index;
else
return parent[index] = setFind(parent[index]); // 路径进行了完全压缩
}
void setUnion(int index_1, int index_2) // 合并操作,按秩合并
{
int root_1 = setFind(index_1); //查找其集合的根节点索引
int root_2 = setFind(index_2);
if (root_1 != root_2) // 两个元素不在同一个集合中,则进行合并操作
{
if (parent[root_1] < parent[root_2]) //根的值越小,则秩越大
parent[root_2] = root_1; // 秩大的作为根,形成的新集合,秩不变
else
{
if (parent[root_1] == parent[root_2]) // 秩相等的情况,合并后,新集合的秩会加一
parent[root_2]--; // 但是,这里用秩的负数来表示,所以变成了减一
parent[root_1] = root_2; // 秩大的作为根,形成的新集合,秩不变,但如果秩相等,新集合的秩会变化
}
}
}
};
C++ 并查集代码
于 2022-01-24 18:59:20 首次发布