并查集
实现两个集合合并,并且好找父节点
这里设计一个方法,那其中一个根结点作为另一个树的子结点
操作总结:
初始化
初始化并查集
这里把所有结点的父节点都为-1 ,
父节点用数组值表示,子节点用下标表示
UFSets::UFSets(int sz) {
size = sz;
parent = new int[size]; //创建双亲数组
for (int i = 0; i < size; i++) {
parent[i] = -1;
}
}
这里找父节点
返回下标就是根,因为根就没有父亲了,值为-1
//函数搜索并返回包含元素x的树的根。
int UFSets::Find(int x) {
while (parent[x] >= 0) {
x = parent[x];
}
return x; //返回下标就是根,因为根就没有父亲了,值为-1
}
找到树根之后,进行合并操作
#ifndef UFsets_h
#define UFsets_h
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
const int DefaultSize1 = 30;
//集合中的各个子集合互不相交
class UFSets {
public:
UFSets(int sz = DefaultSize1);
UFSets(UFSets& R);
~UFSets() {
delete[]parent;
}
UFSets& operator = (UFSets& R); //操作符重载,实现集合赋值
void SimpleUnion(int Root1, int Root2);//子集合并
int Find(int x); //查找x的根
void WeightedUnion(int Root1, int Root2);//压缩高度的合并算法
int CollapsingFind(int i); //使用折叠规则的搜索算法
void output(ostream& out = cout);
friend ostream& operator << (ostream& out, UFSets& R) {
int i;
out << "\n" << string(70, '=');
for (int j = 0; j <= (R.size - 1) / 10; j++) {
out << "\nNode:\t";
for (i = 10 * j; i < 10 * (j + 1) && i < R.size; i++) {
out << setw(6) << i;
}
cout << "\nParent:\t";
for (i = 10 * j; i < 10 * (j + 1) && i < R.size; i++) {
out << setw(6) << R.parent[i];
}
if (i < R.size) {
out << "\n" << string(70, '-');
}
}
out << "\n" << string(70, '=') << "\n";
return out;
}
private:
int* parent; //集合元素数组(双亲表示)
int size; //集合元素的数目
};
#endif
/* UFSets_h */
//初始化并查集
//这里把所有结点的父节点都为-1 ,
//父节点用数组值表示,子节点用下标表示
UFSets::UFSets(int sz) {
size = sz;
parent = new int[size]; //创建双亲数组
for (int i = 0; i < size; i++) {
parent[i] = -1;
}
}
UFSets::UFSets(UFSets& R) {
size = R.size;
parent = new int[size];
for (int i = 0; i < size; i++) {
parent[i] = R.parent[i];
}
}
UFSets& UFSets::operator = (UFSets& R) {
size = R.size;
parent = new int[size];
for (int i = 0; i < size; i++) {
parent[i] = R.parent[i];
}
return *this;
}
//函数搜索并返回包含元素x的树的根。
int UFSets::Find(int x) {
while (parent[x] >= 0) {
x = parent[x];
}
return x; //返回下标就是子孩子
}
//求两个不相交集合Root1与Root2的并(将Root2连接到Root1下面)
void UFSets::SimpleUnion(int Root1, int Root2) {
int r1 = Find(Root1), r2 = Find(Root2);
if (r1 != r2) //两个树根不同
{
/*
parent[r1] += parent[r2];
parent[r2] = r1;
*/
parent[r1] = r2;
}
}