find和join两个优化算法是二选其一的,不需要全部实现
// 并查集主要功能: 1. 合并 2.查询是不是一类
#include <cstdio>
const int N = 1000; // 节点个数
int pre[N]; // 存储每个结点的前驱结点
int rank[N]; // 树的高度
void init(int n) // 初始化函数,对录入的 n个结点进行初始化
{
for (int i = 0; i < n; i++)
{
pre[i] = i; // 每个结点的上级都是自己
rank[i] = 1; // 每个结点构成的树的高度为 1
}
}
// 路径压缩的查找算法
int find(int x)
{
// 根节点
if (pre[x] == x)
return x;
// pre[x]存根节点
return pre[x] = find(pre[x]); // 此代码相当于先找到根结点 rootx,然后 pre[x]=rootx
}
// 判断两个结点是否连通
bool isSame(int x, int y)
{
return find(x) == find(y);
}
//合并为一个集合
bool join(int x, int y)
{
x = find(x);
y = find(y);
//已经属于一个集合
if (x == y)
return false;
// 如果 x的高度大于 y,则令 y的上级为 x
if (rank[x] > rank[y])
pre[y] = x;
else
{
//****容易错的点
if (rank[x] == rank[y])
rank[y]++; // 如果 x的高度和 y的高度相同,则令 y的高度加1
pre[x] = y; // 让 x的上级为 y
}
return true; // 返回 true,表示合并成功
}