#include<iostream>
using namespace std;
//开个数组放数据,如果par[i]>0说明i节点不是所在集合的根节点,par[i]存放的就是i节点的父节点,如果par[i]<0,说明i节点是所在集合的根节点,par[i]的值就是以i节点为根节点的集合的高度,用负数表示
int par[10000];
//查找根节点的函数find,查找到结果后顺便压缩下路径(坍塌规则),压缩路径是为了后面查找更快
int find(int i)
{
//p用于存放找到的根节点
int p = i;
//查找过程
while (par[p] > 0)
{
p = par[p];
}
//路径压缩(坍塌规则)
while (i != p)
{
//保存当前节点的父节点
int next = par[i];
//把当前节点的父节点修改为根节点
par[i] = p;
//继续往上修改
i = next;
}
return p;
}
//合并过程,将a节点所在集合和b节点所在结合合并
void unite(int a, int b)
{
//找到a节点所在集合的根节点
int pa = find(a);
//找到b节点所在集合的根节点
int pb = find(b);
//如果a节点的父节点和b节点的父节点一样,则不用合并
if (pa == pb)
return;
//如果a节点所在集合的高度和b节点所在集合的高度一样,则合并后新集合的高度要加1,自减是因为par数组中保存的是高度的负值
else if (par[pa] == par[pb])
{
par[pa]--;
par[pb] = pa;
}
//如果a节点所在集合的高度比b节点所在结合的高度大,则将b节点所在集合合并到a节点所在集合里面,合并后a节点所在集合高度不变
else if (par[pa] < par[pb])
{
par[pb] = pa;
}
else
{
par[pa] = pb;
}
}
//主函数初始化各种参数
int main()
{
//初始化par数组,每个节点一开始都是一个集合,并且都是所在集合的根节点,所以保存的是所在集合高度的负值-1
memset(par, -1, sizeof(par));
return 0;
}
union_set
最新推荐文章于 2024-07-09 18:04:44 发布