并查集实现

并查集是什么东西?

它是用来管理元素分组情况的一种数据结构。

他可以高效进行两个操作:

  1. 查询a,b是否在同一组
  2. 合并a和b所在的组

萌新可能不知所云,这个结构到底有什么用?

经分析,并查集效率之高超乎想象,对n个元素的并查集进行一次操作的复杂度低于O(logn)

 

我们先说并查集是如何实现的:

也是使用树形结构,但不是二叉树。

每个元素就是一个结点,每组都是一个树。

无需关注它的形状,或哪个节点具体在哪个位置。

 

初始化:

我们现在有n个结点,也就是n个元素。

 

合并:

然后我们就可以合并了,合并方法就是把一个根放到另一颗树的下面,也就是整棵树作为人家的一个子树。

 

查询:

查询两个结点是否是同一组,需要知道这两个结点是不是在一棵树上,让他们分别沿着树向根找,如果两个元素最后走到一个根,他们就在一组。

 

当然,树形结构都存在退化的缺点,对于每种结构,我们都有自己的优化方法,下面我们说明如何避免退化。

  1. 记录每一棵树的高度,合并操作时,高度小的变为高度大的子树即可。
  2. 路径压缩:对于一个节点,只要走到了根节点,就不必再在很深的地方,直接改为连着根即可。进一步优化:其实每一个经过的节点都可以直接连根。

这样查询的时候就能很快地知道根是谁了。

 

下面上代码实现:

和很多树结构一样,我们没必要真的模拟出来,数组中即可。

int p[MAX_N];//父亲
int rank[MAX_N];//高度
//初始化
void gg(int n)
{
    for(int i=0;i<n;i++)
    {
        p[i]=i;//父是自己代表是根
        rank[i]=0;
    }
}
//查询根
int find(int x)
{
    if(p[x]==x)return x;
    return p[x]=find(p[x])//不断把经过的结点连在根
}
//判断是否属于同一组
bool judge(int x,int y)
{
    return find(x)==find(y);//查询结果一样就在一组
}
//合并
void unite(int x,int y)
{
    if(x==y)return;
    if(rank[x]<rank[y])p[x]=y;//深度小,放在大的下面
    else
    {
        p[y]=x;
        if(rank[x]=rank[y])rank[x]++;//一样,y放x后,x深度加一
    }
}

实现很简单,应用有难度,以后有时间更新题。

 

  • 21
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兔老大RabbitMQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值