当前位置: 首页 > news >正文

并查集的实现(朴素版)

         这是C++算法基础-数据结构专栏的第二十九篇文章,专栏详情请见此处


由于作者即将参加CSP,所以到比赛结束前将不再发表文章!

引入

        并查集是一种可以快速合并查找集合的一种数据结构,这次我们将通过三道题来详细讲解并查集(朴素版、维护并查集大小版和维护到祖宗节点距离版),而这次我们要学习朴素版的并查集。

        下面我们就来讲并查集的实现(朴素版)。

定义

        并查集是一种用于管理元素所属集合的数据结构,实现为一个森林,其中每棵树表示一个集合,树中的节点表示对应集合中的元素。

过程

        例题:合并集合

        题目大意:起初一共有n个数,每个数都各自在一个集合中。现在要进行m个操作,操作共两种:将两个数a,b所在的集合合并;询问两个数a,b是否在同一个集合中;

        操作:合并和查找

        并查集,顾名思义,它就是支持两种基本操作的数据结构:并(合并)和查(查找)。它的原理就是用一个数组p[]记录每个节点的祖宗节点,通过对这个数组的更新实现数据之间的联系。刚开始所有节点的根都是它本身。

        首先,我们需要实现一个函数find(),用来寻找一个节点的根,方法很简单,只需不断递归,一直访问现在节点的祖宗节点,直到访问到根节点(即该节点的p[]是本身)。

        首先是第一个操作:合并。合并时只需要将其中一个节点的根的p[]赋值为另一个节点的根。

        第二个操作:查找。查找两个节点是否在同一棵树上,仅仅判断两个节点的find()是否相同即可。

Q:为什么不直接比较p[]呢?

A:因为在合并时,若有两棵树进行合并,可能中途的节点的p[]不会被直接连到根上,所以需要不断寻找才能找到最终的根。

        优化:路径压缩和按秩合并

        接下来我们进行优化,在实现find()函数的过程中,很明显,一路上经过的点都在这个集合中,为了加快后续查询,我们可以将其直接连到根上。这一优化我们称为路径压缩。这个优化大大的降低了时间复杂度。

        有时题目需要保留原有的树的结构,这时我们就不能采用路径压缩了。合并时,我们可以在每棵树的根上记录树的层数,把层数小的树合并到层数大的树,很明显,这样做可以减少合并后树的层数,这叫做按秩合并。

        由于路径压缩的优化程度比按秩合并要大,所以我们一般仅仅采用路径压缩就足够了。课程中也只是提到了按秩合并,并没有讲解,所以在代码中我们也不采用按秩合并。

代码

        下面给出朴素版并查集的实现代码:

int p[N];int find(int x){if(p[x]!=x) p[x]=find(p[x]);return p[x];
}for(int i=1;i<=n;i++) p[i]=i;p[find(a)]=find(b);
        代码解释

        第一行是存储每个节点的祖宗节点的数组;find()函数的作用是寻找根节点;for循环中的内容的作用是初始化;最后一行的作用是合并。

上一篇-Trie树之最大异或对问题    C++算法基础专栏文章    下一篇-并查集的实现(维护并查集大小版版)


每周一更新一篇文章,内容一般是自己总结的经验或是在其他网站上整理的优质内容

点个赞,关注一下呗~

http://www.lryc.cn/news/459930.html

相关文章:

  • WPF 为button动态设置不同的模板
  • 【C++贪心 DFS】2673. 使二叉树所有路径值相等的最小代价|1917
  • 虚幻引擎GAS入门学习笔记(一)
  • Excel:vba实现合并工作表(表头相同)
  • Redis:分布式 - 主从复制
  • el-date-picker设置只有某些日期可选
  • java数据库操作-cnblog
  • HCIP-HarmonyOS Application Developer 习题(九)
  • redis集成到spring boot中使用
  • Spring Boot、Spring MVC和Spring有什么区别
  • Flip动画
  • Java通过RAG构建专属知识问答机器人_超详细
  • 2.1 使用点对点信道的数据链路层
  • 台式机来电自启动设置
  • 【最新华为OD机试E卷-支持在线评测】考勤信息(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
  • netdata保姆级面板介绍
  • 苹果最新论文:LLM只是复杂的模式匹配 而不是真正的逻辑推理
  • Python知识点:基于Python工具,如何使用Scikit-Image进行图像处理与分析
  • MongoDB初学者入门教学:与MySQL的对比理解
  • Oracle AI Vector Search
  • 基于SpringBoot的健身会员管理系统实战分享
  • Elasticsearch高级搜索技术-结构化数据搜索
  • ffmpeg面向对象——类所属的方法探索
  • TensorRT-LLM七日谈 Day3
  • 如何使用Pandas库处理大型数据集?
  • XHR 创建对象
  • # 在执行 rpm 卸载软件使用 nodeps 参数时,报错 error: package nodeps is not installed 分析
  • C++的类和动态内存分配(深拷贝与浅拷贝)并实现自己的string类
  • 通过观测云 DataKit Extension 接入 AWS Lambda 最佳实践
  • MySQL-三范式 视图