C++实现树 - 08 并查集

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

并查集定义

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

1.jpg

查找

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

2.jpg

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

3.jpg

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

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

4.jpg

全部代码

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

一共有 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;
}

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

目录
相关文章
|
6月前
|
Java C++
部落(pta)(并查集) Java以及C++
部落(pta)(并查集) Java以及C++
55 2
|
6月前
|
算法 测试技术 C++
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(下)
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(下)
|
6月前
|
C++ 容器
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(上)
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(上)
|
2月前
|
存储 C++
【C++】AVL树
AVL树是一种自平衡二叉搜索树:它以苏联科学家Georgy Adelson-Velsky和Evgenii Landis的名字命名。
27 2
|
6月前
|
存储 C++ 容器
c++的学习之路:26、AVL树
c++的学习之路:26、AVL树
51 0
|
3月前
|
C++ 容器
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
34 5
|
4月前
|
C++
【C++】手撕AVL树(下)
【C++】手撕AVL树(下)
51 1
|
4月前
|
算法 测试技术 C++
【C++高阶】掌握AVL树:构建与维护平衡二叉搜索树的艺术
【C++高阶】掌握AVL树:构建与维护平衡二叉搜索树的艺术
35 2
|
4月前
|
Java C++ Python
【C++】手撕AVL树(上)
【C++】手撕AVL树(上)
52 0
|
6月前
|
算法 C语言 容器
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(下)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
66 7