C++实现树 - 08 并查集

数据结构与算法专栏 —— C++实现

写在前面:
这一讲我们来讲一个非常实用的小技巧即并查集,一开始理解起来可能需要一点时间,但是它的实际代码其实非常的短,在后面的内容中我们也会用到。

并查集定义

并查集是一种非常精巧而实用的树形数据结构,他主要是处理一些不相交集合的合并和查询的问题。比如我给定一些数字并给定它们属于哪个集合,并且每次询问当中的两个数字时可以告诉我这两个数字是否处于同一个集合,这就是一个典型的并查集问题。

在这里插入图片描述

查找

我们可以利用一个数组来存储每个元素的相邻结点:

在这里插入图片描述

每次合并两个结点时就只用将一个结点数组中的值改成另一个结点的数值即可,假如我们想合并(4,3),(3,2),(2,1),在图中显示出来就会得到下面的结果:

在这里插入图片描述

由此我们也可以发现这样子做如果遇到最坏情况时,会使查找的时间复杂度非常的大,这时候我们可以通过路径压缩来解决这一问题。

路径压缩就是在每次查找时,令查找路径上的每个节点都直接指向根节点。

在这里插入图片描述

全部代码

为了方便大家理解,这里放上一个例题:

一共有 n 个数,编号是 1∼n,最开始每个数各自在一个集合中。

现在要进行 m 个操作,操作共有两种:

  1. M a b,将编号为 a 和 b 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;
  2. Q a b,询问编号为 a 和 b 的两个数是否在同一个集合中;
#include<bits/stdc++.h>
using namespace std;

int fa[100010];	//存储所有结点的父结点

//查找操作
int find(int x)
{
    if (fa[x] != x)    fa[x] = find(fa[x]);	//查找同时进行路径压缩
    return fa[x];
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        fa[i] = i;
    char op;
    int a, b;
    while (m--)
    {
        scanf("%s%d%d", &op, &a, &b);
        if (op == 'M') fa[find(a)] = find(b);
        else
        {
            if (find(a) == find(b))    puts("Yes");
            else    puts("No");
        }
    }
    return 0;
}

如果大家有什么问题的话,欢迎在下方评论区进行讨论哦~

【上一讲】树 - 07 平衡二叉树

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值