并查集,真好用,一次AC不是梦!

请添加图片描述

文章目录

  • 🚀前言
  • 🚀并查集
  • 🚀并查集的两个优化
    • ✈️路径压缩
    • ✈️按秩合并
  • 🚀并查集代码模板

🚀前言

大家好啊!今天阿辉来给大家介绍一种简洁而优雅的数据结构——并查集,不知道各位是否了解它,如果你在题解区见到并查集,想必各位一定见过类似下面这样的评论
在这里插入图片描述
在这里插入图片描述
好了,阿辉也不卖关子了,开始咱们今天的学习吧!!!!

🚀并查集

并查集是一种树形数据结构,每一棵树代表一个集合,支持两种操作:

  • isSameSet方法:查找两个元素是否为同一集合
  • uinionSet方法:合并两个集合

并查集与二叉树这类树形结构并不相同,二叉树的每个节点都维护着他的两个子节点,而并查集则是每个节点都指向其父节点直至根节点,而根节点指向自己,类似于下图这样的结构
请添加图片描述

根节点15指向自己,他们的子节点指向其父节点,一棵树代表一个集合,对于每一棵树它的根节点又被称为代表节点,因为集合中的任意节点都能找到其根节点,判断两元素是否在同一集合就是判断量元素的根节点(代表节点)是否相同,这也就是isSameSet方法

15两个集合如何合并呢?
这很简单只需要其中一棵树的代表节点指向另一棵树的代表节点即可,如下图:
请添加图片描述
很明显,isSameSetunionSet方法都需要一个find方法来找到元素的代表节点从而实现合并和查询功能,find方法的实现也是很容易,拿到一个节点一直往上找当自己就是父节点时,就找到代表节点了。
但并查集的厉害还未展现
并查集的厉害之处在于,它的isSameSetunionSet方法的单次操作的均摊时间复杂度可以达到接近 O ( 1 ) O(1) O(1),也就是说在通常情况下对于并查集的单次操作我们认为是常数时间

各位是不觉得我在开玩笑,因为很明显集合元素的增长会使得树的高度不断扩大,会导致find方法的效率变差,没错是这样的,不过并查集的两个优化会使得find方法异常高效近乎就是常数时间

🚀并查集的两个优化

✈️路径压缩

并查集的第一个优化就是路径压缩,实际操作呢也很简单,上图
请添加图片描述
也就是上面这样高度为4的树在经历一次find后,虽然这一次遍历了4个节点但是下一次find操作剩下的节点只需要常数时间就能找到代表节点,即便一个高度为n的数如果从底部find一次,今后剩下的节点都直接指向代表节点,他们进行find操作都是常数时间,每次find操作近乎 O ( 1 ) O(1) O(1)的时间复杂度,好吧,很遗憾阿辉不会证明,但是上面的解释相信大家能感受到并查集确实能很快
其实在各类算法竞赛中往往并查集只用到路径压缩这一种优化,就可以认为并查集的各种操作时间复杂度为 O ( 1 ) O(1) O(1)

并查集于1964年发表,于1989年才证明其时间复杂度近乎常数时间

并查集的证明很难,各位有兴趣可以研究🧐

✈️按秩合并

相信各位看到这个按秩合并很懵,没关系我一开始懵

“按秩合并”是一种优化并查集性能的技术。在这里,“秩”可以理解为树的“高度”或“深度”,代表集合的某种“大小”指标。按秩合并的基本思想是总是将较小的树连接到较大的树上,这样可以避免树变得过高,从而减少查找时的路径长度

很官方的话,总感觉不像人说的,其实秩就可以理解为,一个集合中的元素个数,当两个集合合并时,元素个数少的要挂在元素多的集合下,一般情况下元素多的集合的这棵树也相对较高,为了尽量降低树的高度,所以要按秩合并(不如小挂大是吧!)

🚀并查集代码模板

以数组实现并查集,最经典的用法,附上牛客并查集模板测试链接

//MAXN根据题目的数据量进行更改
#define MAXN 101
//用father数组实现每个元素的父节点,比如题目数据量是100,就开101大小的空间
//数组下表与数组元素属于天然的<int,int>的映射表
int father[MAXN];
//size数组里面存着每个集合的元素个数,由代表节点映射
int size[MAXN];
//build方法相当于对并查集初始化
void build(int n){for(int i = 0;i < n;++i){father[i] = i;//一开始每个元素的父节点是自己size[i] = 1;//每个集合都只有一个元素}
}
//find方法,找集合的代表节点
//一个三目运算很优雅,懒人专用
//int find(int x){//return father[x] = x != father[x] ? find(father[x]) : x;
//}
int find(int x){if(x != father[x]){//如果父节点不是自己就调递归//找到代表节点后返回到上一级递归时,先把当前节点的父节点直接改成代表节点father[x] = find(father[x]);}return father[x];//然后返回当前节点的父节点父节点
}
bool isSameSet(int x,int y){return find(x) == find(y);//代表节点相同则在同一集合,否则不在
}
void unionSet(int x,int y){int fx = find(x);//x所在集合代表节点int fy = find(y);//y所在集合代表节点//小挂大if(size[fx] < size[fy]){father[fx] = fy;size[fy] += size[fx];//同时更新新集合元素个数}else{father[fy] = fx;size[fx] += size[fy];//同时更新新集合元素个数}
}

一般在刷题的过程中,并查集的使用往往只需要路径压缩这一优化即可,更简洁并查集模板附上洛谷并查集模板测试链接

#define MAXN 100
int find[MAXN];
void build(int n){for(int i = 0;i < n;++i){father[i] = i;}
}
int find(int x){return father[x] = father[x] != x ? find(father[x]) : x;
}
bool isSameSet(int x,int y){return find(x) == find(y);
}
void unionSet(int x,int y){father[find(x)] = find(y);//没有小挂大了,谁挂谁无所谓
}

虽然很少用到小挂大,但是size并不是用不到,并查集可以给每个集合加上标签,就像size表示大小,还可以根据需要给不同的集合加上标签


请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/689731.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ssh连接服务器需要子网掩码吗?

IP寻址需要同时知道IP地址和子网掩码&#xff0c;但是在通过ssh连接服务器时&#xff0c;只需要知道IP地址和端口号就可以了&#xff0c;ssh通讯为什么不需要子网掩码呢。在不知道子网掩码的前提下&#xff0c;可以正确找到IP对应的主机吗&#xff1f; 不需要&#xff0c;SSH&a…

桌面显示器应用Type-C接口

随着科技的飞速发展&#xff0c;桌面显示器作为我们日常工作中不可或缺的设备之一&#xff0c;也在不断地更新换代。其中&#xff0c;Type-C接口的应用成为了桌面显示器发展的一个重要趋势。那么&#xff0c;桌面显示器应用Type-C接口究竟有什么好处呢&#xff1f; 首先&#x…

职场隐私守则:关系再好也别碰这些“雷区”

在职场中&#xff0c;与同事建立良好的关系是非常重要的&#xff0c;它有助于提高工作效率、增进团队协作&#xff0c;并且能够为日常的工作带来便利。 然而&#xff0c;即便与同事的关系再亲密&#xff0c;也有一些隐私话题是绝对不能轻易透露的。 在与同事和领导相处时&…

文章复现 | 差异分析和PPI网络构建

原文链接&#xff1a;差异分析和PPI网路图绘制教程 写在前面 在原文中&#xff0c;作者获得285个DEG&#xff0c;在此推文中共获得601个DEG。小杜的猜想是标准化的水段不同的原因吧&#xff0c;或是其他的原因。此外&#xff0c;惊奇的发现发表医学类的文章在附件中都不提供相…

燃气热水器水箱的气密性测试密封方案介绍—格雷希尔快速接头

家用燃气热水器的气密性检测是保障其安全性的重要环节之一&#xff0c;如热水器的水箱&#xff0c;它的周围缠绕着一圈铜管&#xff0c;这圈铜管和水箱之间有数量不等的焊接点&#xff0c;为了保证热水器的正常运行&#xff0c;必须要对它们进行气密性测试。   燃气热水器水箱…

文件且目录损坏无法读取怎么办?

文件及目录损坏无法读取是计算机使用过程中的常见故障&#xff0c;这可能是由于多种原因导致的&#xff0c;例如硬件故障、文件系统错误、病毒感染或不当操作等。本文将对这一问题进行深入分析&#xff0c;探讨其根本原因&#xff0c;并提供相应的解决方法&#xff0c;包括数据…

Collectors.toMap使用记录

最近看到一行比较有趣的代码&#xff0c;他的功能就是将List转换为Map。我觉得挺有意思的&#xff0c;先前没遇到过&#xff0c;于是打算写篇文章记录一下。 public enum CodeEnum {USER("user"),AGE("age"),INTEREST("interest"),;private Str…

揭秘:一行代码搞定.Net API高并发的烦恼

高并发下的接口请求重复提交问题 在.Net开发中&#xff0c;我们经常遇到用户疯狂点击同一按钮&#xff0c;或者服务响应慢时重复发送请求&#xff0c;导致数据重复添加或混乱。这不仅浪费资源&#xff0c;更会得到错误的业务结果。如何高效解决这一普遍问题呢&#xff1f; 常规…

影响效果图渲染的因素有哪些?渲染100邀请码1a12

效果图对很多行业是刚需&#xff0c;特别是视觉行业&#xff0c;一张好的效果图非常重要&#xff0c;影响效果图渲染的因素有很多&#xff0c;它们是哪些呢&#xff1f;一起来看看吧。 1、渲染引擎 渲染引擎对效果图的渲染至关重要&#xff0c;目前市面上有很多渲染引擎&#x…

阅读笔记(SOFT COMPUTING 2018)Seam elimination based on Curvelet for image stitching

参考文献&#xff1a; Wang Z, Yang Z. Seam elimination based on Curvelet for image stitching[J]. Soft Computing, 2018: 1-16. 注&#xff1a;SOFT COMPUTING 大类学科小类学科Top期刊综述期刊工程技术 3区 COMPUTER SCIENCE, ARTIFICIAL INTELLIGENCE 计算机&#xf…

6.1.0 MPLS LDP动态分配

手动写静态MPLS的转发路径&#xff0c;不仅不方便管理&#xff0c;同时配置量也非常多&#xff0c;每台设备都需要去做配置。为了方便管理且去除繁琐的配置&#xff0c;就需要使用到LDP动态标签分发协议了。 标签分发协议LDP&#xff08;Label Distribution Protocol&#xff…

迈向AI时代:掌握Python编程与ChatGPT的强强联手

文章目录 一、ChatGPT与Python编程的结合二、利用ChatGPT学习Python编程的优势三、如何使用ChatGPT学习Python编程四、学习技巧与建议《码上行动&#xff1a;用ChatGPT学会Python编程》特色内容简介作者简介目录获取方式 随着人工智能技术的飞速发展&#xff0c;编程已经成为了…

【漏洞复现-通达OA】通达OA report_bi存在前台SQL注入漏洞

一、漏洞简介 通达OA(Office Anywhere网络智能办公系统)是由北京通达信科科技有限公司自主研发的协同办公自动化软件,是与中国企业管理实践相结合形成的综合管理办公平台。通达OA为各行业不同规模的众多用户提供信息化管理能力,包括流程审批、行政办公、日常事务、数据统计…

Unity3D Shader 素描风格渲染管线实现详解

前言 在游戏开发中&#xff0c;渲染效果是非常重要的一部分&#xff0c;它可以直接影响游戏的视觉效果和玩家的体验。而素描风格的渲染效果是一种非常独特和有趣的风格&#xff0c;可以为游戏增添一种艺术氛围。在Unity3D中&#xff0c;可以通过编写Shader来实现素描风格的渲染…

java面试

一、java基础篇 1.接口和抽象类的区别 相似点&#xff1a; &#xff08;1&#xff09;接口和抽象类都不能被实例化 &#xff08;2&#xff09;实现接口或继承抽象类的普通子类都必须实现这些抽象方法 不同点&#xff1a; &#xff08;1&#xff09;抽象类可以包含普通方法…

YOLOv8 | 代码逐行解析(二) | 从yaml文件到模型定义(代码逐行注释,小白必看)

👑欢迎大家订阅我的专栏一起学习YOLO👑 一、本文介绍 本文给大家带来的是YOLOv8项目的解读,之前给大家分析了YOLOv8的项目文件分析,这一篇文章给大家带来的是模型训练从我们的yaml文件定义到模型的定义部分的讲解,我们一般只知道如何去训练模型,和配置yaml文件,但是…

STM32 学习2 库函数控制GPIO输出

STM32 学习2 库函数控制GPIO输出 一、GPIO寄存器介绍1. GPIO简介2. GPIO功能&#xff08;1&#xff09;模式分类&#xff08;2&#xff09;模式设置方法MODE[1:0]&#xff1a;模式控制&#xff0c;用于配置端口引脚的模式&#xff1a;CNF[1:0]&#xff1a;配置引脚输出速度&…

【vue+leaflet】vue项目中使用leaflet绘制室内平面图、leaflet.pm在平面图中绘制点、线、面图层(一)

效果图: 一,插件安装 npm i leaflet --save // 我的版本^1.9.4 npm i leaflet.pm --save // 我的版本^2.2.0附官网链接: leaflet官网: https://leafletjs.com/index.html leaflet.pm官网: https://www.npmjs.com/package/leaflet.pm?activeTabreadme 二,模块引入 因为我…

Android MMKV 接入+ 替换原生 SP + 原生 SP 数据迁移

背景:项目中一直使用的是原生 SP,众所周知,使用原生 SP 存在卡顿性能问题。公司的性能监控平台抓到不少原生 SP 导致的 ANR 问题: java.io.FileDescriptor.sync (FileDescriptor.java) android.os.FileUtils.sync (FileUtils.java:256) android.app.SharedPreferencesImpl.…

CentOS7.6安装RocksDB

一、简介 RocksDB是使用C编写的嵌入式kv存储引擎&#xff0c;其键值均允许使用二进制流。由Facebook基于levelDB开发&#xff0c; 提供向后兼容的levelDB API。 RocksDB针对Flash存储进行优化&#xff0c;延迟极小。RocksDB使用LSM存储引擎&#xff0c;纯C编写。Java版本Rock…