首页 > 其他分享 >数据结构——并查集

数据结构——并查集

时间:2023-04-27 16:00:12浏览次数:42  
标签:结点 递归 int 查集 树根 集合 数据结构 find

并查集的作用:

可以在近乎O(1)的时间内完成以下两个操作

1、将两个集合合并

2、询问两个元素是否在一个集合中


 基本原理:

用“树”的形式来维护每一个集合,树根的编号就是整个集合的编号,每个结点存储它的父结点(如:p[x]表示x的父结点)


问题1:如何判断树根?    A:if(p[x]==x),当前x就是树根了,因为除了树根其他的结点存储的都是它的父结点。

问题2:如何求x的集合编号?     A:while(p[x]!=x) x=p[x]; 

问题3:如何合并两个集合?       A:假设px是x的集合编号,py是y的集合编号,则p[px]=py,即将x集合的树根连接到y集合的树根下作为其子结点。

 

当前缺点及其优化?

缺点:这样子第二个操作,即求x的集合编号还是太慢了,需要while循环树的高度,需要优化。

优化:路径压缩!在第一遍求x的根结点时,一旦找到其根结点,将其路径上的所有结点的父结点都变成这个根结点,即树的高度变小了。

左图为路径压缩的简单图示,初始时树用黑色连线连接,从叶子结点找到根结点后,将路径上的所有非根结点的父结点都变成根结点,用红色连线表示。


 代码实现:

题目参考acwing模板题:

836. 合并集合 - AcWing题库

代码参考:

#include<iostream>
using namespace std;
const int N=100010;
int p[N];
int find(int x){
    if(p[x]!=x)p[x]=find(p[x]);//巧妙的find函数核心,递归的同时实现了路径压缩,递归第一层找父结点,第二层找父结点......一直递归下去,找到根结点之后会原路返回,将所有路径上的结点的父结点都变成根结点
    //递归需要加以限制,不进行限制的递归就会爆栈
    return p[x];
    //如果是下面这种写法,则没有进行状态压缩,只找了根结点,会超时
    // while(p[x]!=x)x=p[x];
    // return x;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        p[i]=i;
    }
    while(m--){
        char op;
        cin>>op;
        int a,b;
        cin>>a>>b;
        if(op=='M'){
            p[find(a)]=find(b);
        }
        else{
            if(find(a)==find(b))cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }
    }
    return 0;
}

 

标签:结点,递归,int,查集,树根,集合,数据结构,find
From: https://www.cnblogs.com/Pworldlet/p/17359195.html

相关文章

  • 并查集の进阶用法
    普通并查集我们在处理问题的时候,可能会遇到一些需要维护每个元素所在的集合的问题,而并查集却恰好完美解决了这个问题。对于普通的并查集,他支持的操作比较少,只有合并和查询,合并是指把两个集合合并成一个,而查询是询问两个元素是否在同一集合内;对于这两种操作,我们可以用一个数组\(......
  • OpenJ_Bailian 4081 树的转换 数据结构
    题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=412663题意:我们都知道用“左儿子右兄弟”的方法可以将一棵一般的树转换为二叉树,如:00/|\/123===>1/\......
  • 山东大学数据结构实验11 搜索树
    描述创建带索引的二叉搜索树类。存储结构使用链表,提供操作:插入、删除、按名次删除、查找、按名次查找、升序输出所有元素。格式输入格式输入第一行一个数字m(m<=1000000),表示有m个操作。接下来m行,每一行有两个数字a,b:当输入的第一个数字a为0时,输入的第二个数字b表示......
  • 山东大学数据结构实验10 堆及其应用
    内容创建最小堆类。最小堆的存储结构使用数组。提供操作:插入、删除、初始化。题目第一个操作是建堆操作,接下来是对堆的插入和删除操作,插入和删除都在建好的堆上操作。格式输入第一行一个数n(n<=5000),代表堆的大小。第二行n个数,代表堆的各个元素。第三行一个数m(m<=1000),代......
  • 山东大学数据结构实验9 二叉树操作
    描述创建二叉树类。二叉树的存储结构使用链表。提供操作:前序遍历、中序遍历、后序遍历、层次遍历、计算二叉树结点数目、计算二叉树高度。格式输入格式第一行为一个数字n(10<=n<=100000),表示有这棵树有n个节点,编号为1~n。之后n行每行两个数字,第i行的两个数字a、b表示编号......
  • 山东大学数据结构实验8 散列表
    要求使用线性开型寻址实现描述给定散列函数的除数D和操作数m,输出每次操作后的状态。有以下三种操作:插入x,若散列表已存在x,输出“Existed”,否则插入x到散列表中,输出所在的下标。查询x,若散列表不含有x,输出“-1”,否则输出x对应下标。删除x,若散列表不含有x,输出“NotFound”,否......
  • C++数据结构(树)
    树是一种递归定义的数据结构,如果树中节点的各子树从左到右是有次序的,不能互换,则称该树为有序树,否则叫无序树。关于树的节点:节点拥有的子树的个数叫做节点的度如果度为0,那么该节点叫做叶节点或终端节点,除了根节点外的分支节点称为内部节点树的度是各节点度的最大值。节点的子......
  • 什么是数据结构?
    数据结构研究计算机数据间关系,包括数据的逻辑结构和存储结构及其操作。我们接触一种数据结构,一定要掌握这三个方面基本概念1.数据(Data)数据即信息的载体,是能够输入到计算机中并且能被计算机识别、存储和处理的符号总称。2.数据元素(DataElement)数据......
  • 初识数据结构
    什么是数据结构,数据结构可以理解为我们规定数据元素之间具有某种关系或规则,程序员根据这些规则能够更好的管理和操作这些数据。数据元素的关系包括三种:线性关系——1:1线性关系即为数据是一对一的关系,即除了开头的数据元素和最后的数据元素,其他如何应该数据元素有......
  • 2023年电子科技大学ACM-ICPC暑假前集训-数据结构
    Preface学校针对大一新生的暑假前集训的第一个专题DS,由于要求集体写题解就顺便把写好的发上来了由于下面都写了题意所以直接看也能有很多收获,当然非电专的学生的话就没法交题了代码的话由于专题还没结束怕放上来然后被CV导致被爆破,所以应该在这周六专题结束后会放上来下面都是......