【数据结构高阶】并查集

news2025/1/20 12:00:29

目录

一、什么是并查集

二、并查集的原理

三、并查集的作用

四、并查集的代码实现


一、什么是并查集

在一些应用问题中,需要将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个 单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一 个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(union-find set)。

二、并查集的原理

下面来看一个例子:某算法竞赛今年全国决赛总共有10人,4人来自西安,3人来自安徽,3人来自上海,10个人均来自不同的学校,起先互不相识,每个学生都是一个独立的小团体,现给这些学生进行编号:{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

再用一个数组用来存储该小集体,数组下标表示学生的编号,数组中存储的数字我们先将其全部设为-1(为什么是-1下文会具体讲解):

竞赛时,每个地方的学生自发组织成小分队一起合作,于是:西安学生小分队s1={0,6,7,8},安徽学生小分队s2={1,4,9},上海学生小分队s3={2,3,5}就相互认识了,10个人形成了三个小团体。假设右三个群主0,1,2担任队长,负责组员的管理

这样子这10个学生就分成了三个组,我们用树的方式来表示一下:

下面我们使用双亲表示法,在之前建立的数组中进行三个小组的划分:

划分方法为:如果元素下标所表示的学生是组长不进行任何操作;如果下标所表示的学生是组员就将其下标的所对应的元素值加到所属组长的元素值上,再将自己的元素值改为组长所在元素下标:

这样处理过后我们可以发现:数组中存储的数字如果为负数,意味着该值所在的元素下标对应的学生是组长(树的根),其绝对值也代表该小集体中具有成员的个数(树的节点数);如果为不为负数,意味着该值所在的元素下标对应的学生是组员(树的叶子),其值也代表组长所在下标(指向自己的根)

按照上面的方法我们就可以使用数组来实现多棵树(森林)的表示了(和堆有点相似)

在比赛结束后,西安小分队中8号同学与安徽小分队4号同学奇迹般的走到了一起,两个小圈子的学生相互介绍,最后成为了以0号同学为主导的一个小圈子:

那树的形状发生了变化,数组对应的数据也会进行变化:

在数组中,一棵树要和另一棵树进行融合,先要找到要融合数据所对应的下标:例子里是4号同学,对应4号下标

再判断下标所在元素的数值,数值为正就继续找数值所对应的下标元素,一直找到数值为负的下标为止(找到要融合数据所在的根):先找到4号下标对应的数据是1,不是负数,那就继续找到1号下标所在的元素,其数值为-3,满足条件

最后将找到的根节点的数值加到另一棵树的根节点的数值上,再将其原本的根节点的数值改为另一棵树的根节点的下标:

现在0集合有7个人,2集合有3个人,总共两个朋友圈。

三、并查集的作用

通过以上例子可知,并查集一般可以解决一下问题:

1. 查找元素属于哪个集合,沿着数组表示树形关系以上一直找到根(即:树中中元素为负数的位置)

2. 查看两个元素是否属于同一个集合,沿着数组表示的树形关系往上一直找到树的根,如果根相同表明在同一个集合,否则不在

3. 将两个集合归并成一个集合,将两个集合中的元素合并,将一个集合名称改成另一个集合的名称

4. 集合的个数遍历数组,数组中元素为负数的个数即为集合的个数。

四、并查集的代码实现

#include<iostream>
#include<vector>

using namespace std;

class UnionFindSet
{
public:
	UnionFindSet(size_t n)//初始化数据
		:_ufs(n,-1)
	{}

	int FindRoot(int n)//查找元素的根节点
	{
		int parent = n;
		while (_ufs[parent] >= 0)
		{
			parent = _ufs[parent];
		}
		return parent;
	}

	void Union(int x, int y)//合并两个元素所在树
	{
		int root1 = FindRoot(x);
		int root2 = FindRoot(y);
		if (root1 == root2)//元素所在树都一样就没必要合并了
			return;
		if (root1 > root2)//取较小值的根节点来合并
			swap(root1, root2);
		_ufs[root1] += _ufs[root2];
		_ufs[root2] = root1;
	}

	bool InSet(int x, int y)//判断两个元素是否在同一棵树
	{
		return FindRoot(x) == FindRoot(y);
	}

	size_t SetSize()//返回并查集中树的个数
	{
		size_t size = 0;
		for (auto e : _ufs)
		{
			if (e < 0)
				++size;
		}
		return size;
	}

private:
	vector<int> _ufs;
};

上述的代码实现的只是一个基本的并查集,如果并不想用元素下标来直接表示数据类型,我们可以使用map来建立对应的映射关系

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

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

相关文章

小型园区配置示例——华为

小型园区配置示例 组网图形 图1 小型园区组网图 组网需求数据规划配置思路操作步骤业务验证 组网需求 某企业划分为A、B两个部门&#xff0c;企业中的用户可以相互访问&#xff0c;并且企业中的用户可访问Internet。 如图1所示&#xff0c;在小型园区中&#xff0c;S2700…

01_Maven

文章目录 Maven安装MavenMaven的工作流程配置MavenMaven的使用module和project的关系如何用Maven导包 如何用Maven进行项目构建指令介绍clean指令compile指令package指令install指令 Maven的依赖管理如何导包scope作用域依赖传递依赖冲突 使用Maven开发项目Junit如何使用Junit …

(黑马出品_03)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

&#xff08;黑马出品_03&#xff09;SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术Docker 今日目标1.初识Docker1.1.什么是Docker1.1.1.应用部署的环境问题1.1.2.Docker解决依赖兼容问题1.1.3.Docker解决操作系统环境差异1.1.4.小结 1.2…

代码学习记录11

随想录日记part11 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.04 主要内容&#xff1a;今天的主要内容是深入了解栈和队列中比较难的题录类型&#xff1a;滑动窗口最大值与前 K K K 个高频元素&#xff0c;最后对于这三天学习的队列和栈的知识进行总结。…

深圳市萨科微半导体有限公司一直研究新材料新工艺,不断推出新产品,驱动公司不断发展

深圳市萨科微半导体有限公司一直研究新材料新工艺&#xff0c;不断推出新产品&#xff0c;驱动公司不断发展。最近萨科微推出SL40T120FL系列IGBT单管&#xff0c;和CMOS运算放大器SLA333等产品&#xff0c;为新能源汽车、太阳能光伏、交流电机、变频器、开关电源和工业伺服器行…

如何应对IT服务交付中的问题?看了本文DevOps就懂了

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

Java常用类库:Math类

在Java编程语言中&#xff0c;java.lang.Math类提供了一系列用于执行基本数学运算的静态方法。这些方法允许你执行各种数学计算&#xff0c;如三角函数、指数函数、对数函数、取整函数等。在本教程中&#xff0c;我们将介绍Math类的常用方法及其用法。 常用方法 以下是Math类…

线性代数 --- 特征值与特征向量

特征值与特征向量 已知任意向量x&#xff0c;现有矩阵A对x进行操作后&#xff0c;得到新的向量Ax。这就好比是自变量x与函数f(x)的关系一样&#xff0c;向量x通过类似“函数”的处理得到了一个新的向量Ax。这个新的向量可能和原向量x方向相同&#xff0c;也可能不同(事实上大多…

1911_野火FreeRTOS教程阅读笔记_请求任务切换

1911_野火FreeRTOS教程阅读笔记_请求任务切换 全部学习汇总&#xff1a; g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 还有一部分任务切换请求的代码没有分析。 实现上是一个宏定义&#xff0c;实现的工作主要的核心点还是请求PendSV的exception。当这个调用的时候&#xff0c;下…

基于AM62X+FPGA/MCU的B码对时定制化整机解决方案

什么是IRIG-B码对时 IRIG-B(inter-range instrumentationgroup-B)码是一种时间同步标准&#xff0c;通常用于精确的时间测量和数据同步&#xff0c;广泛应用于电力、通信、航空等领域。 IRIG-B码为每秒一帧的时间串码&#xff0c;一帧串码中包含100个码元&#xff0c;频率为1K…

STM32控制气泵和电磁阀实现

一、功能简介 使用STM32控制气泵和电磁阀的开和关&#xff0c;气泵和电磁阀的供电电压为12V。 二、实现过程 1、气泵和电磁阀的开和关均为开关量&#xff0c;实现控制方法有多种&#xff0c;比如继电器&#xff0c;但是继电器动作有噪声且体积较大&#xff0c;更好的方法为使…

【YARN】详解 YARN 中的 ResourceManager

详解 YARN 中的 ResourceManager 1.ResourceManager 核心功能2.通信&#xff08;与三个角色通信&#xff09;3.模块简介3.1 用户交互模块3.2 NM 管理模块3.3 AM 管理模块3.4 Application 管理模块3.5 状态机模块3.6 安全模块3.7 资源分配模块 4.模块详解​​4.1 用户交互模块4.…

如何使用ArcGIS Pro进行坡度分析

坡度分析是地理信息系统中一种常见的空间分析方法&#xff0c;用于计算地表或地形的坡度&#xff0c;这里为大家介绍一下如何使用ArcGIS Pro进行坡度分析&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的DEM数据&#xff0c;除了DEM数据&…

一般情况下使用耳机壳UV树脂制作耳机壳的成本是多少?

一般情况下使用耳机壳UV树脂制作耳机壳的成本是多少&#xff1f; 使用耳机壳UV树脂制作耳机壳的成本主要包括材料成本、加工成本和其他附加成本。 材料成本主要取决于所采购的UV树脂的数量和单价。如果购买数量较大&#xff0c;单价可能会较低。市场上不同品牌和型号的UV树脂…

ubuntu 20.04 安装 huggingface transformers 环境

1. 安装 cuda 大多数新发布的大语言模型使用了较新的 PyTorch v2.0 版本&#xff0c;Pytorch 官方认为 CUDA 最低版本是 11.8 以及匹配的 GPU 驱动版本。详情见Pytorch官方 如下图&#xff1a; 1.1 下载 cuda cuda 12.1 官方网站&#xff1a; 下载&#xff1a; $wget htt…

部署LVS负载均衡架构

目录 一、ipvsadm 工具 二、NAT模式下部署LVS负载均衡 1、部署NFS共享存储服务器 1.1 安装NFS软件 1.2 新建共享目录和站点文件 1.3 设置共享策略 2、部署节点服务器1 2.1 安装并启动nginx软件 2.2 挂载共享目录到网页站点目录 2.3 修改网关 3、部署节点服务器2 3.…

【网络应用层协议】【MQTT】详解消息队列遥测传输协议MQTT(超详细)

目录 1. MQTT 协议简介 2. MQTT 的特点 3. MQTT 协议原理 4. MQTT协议中的订阅、主题、会话 1. MQTT 协议简介 MQTT&#xff08; Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议 &#xff09;是一种消息列队传输协议&#xff0c;采用订阅、发布机制&…

coqui-ai/TTS 案例model文件

GitHub - coqui-ai/TTS: &#x1f438;&#x1f4ac; - a deep learning toolkit for Text-to-Speech, battle-tested in research and production Coqui AI的TTS是一款开源深度学习文本转语音工具&#xff0c;以高质量、多语言合成著称。它提供超过1100种语言的预训练模型库&…

递增三元组(第九届蓝桥杯)

文章目录 题目原题链接思路分析二分做法1二分做法2双指针做法前缀和解法 题目 原题链接 递增三元组 思路分析 由时间复杂度可知需要至少优化到 O ( n l o g n ) O(nlogn) O(nlogn)才行 而纯暴力枚举三个数组的话&#xff1a; O ( n 3 ) O(n^3) O(n3) 可以考虑将b[]作为标志&…

onlyoffice监听https

修改onlyoffice 在开始将您的ONLYOFFICE Docs切换到HTTPS协议之前&#xff0c;您需要创建一个安全证书和证书私钥。将它们放到安装ONLYOFFICE Docs的计算机上的一个文件夹中。 获得证书后&#xff0c;请执行以下步骤&#xff1a; 所有命令都应以管理员权限执行。要以管理员身份…