[数据结构]并查集--C++版本的实现代码

目录

并查集的基本框架

查找一个元素在哪一个集合

判断两个元素是否在同一个集合

将两个集合进行合并

查询有多少组

测试


        大学班级的同学会来自于五湖四海,每个人的家乡可能都不相同,那么如何将相同省份的同学连接到一块,也就是按省份进行分组呢?并查集就可以很好的解决该问题,并查集是一个森林,他内部的每一棵多叉树,都是一个按照特定条件划分出来的相同属性的集合。

并查集的基本框架

        并查集是使用数组的形式去表示森林的结构,森林中的每一颗树的每一个节点,采用的是双亲指针法,也就是说每一个节点,只能找到他的父节点,没法向下找子节点。每个存储的元素会被映射为一个下标序号,数组的值,存放的是他的父节点的下标。例如a[i] = n;那么就代表序号为i的元素的父节点是序号为n的元素。

        所以说除了维护一个并查集数组之外,还要维护一个哈希map来进行字符串转下标的结构,和一个数组用来进行下标转字符串的操作。如果说数据本身就是数字的话,那就没必要了。

        初始化的时候,设置为-1,是因为首先让每一个元素都是一个特定的集合,然后根据情况,调用方法逐步的进行元素的合并操作,来完成并查集的构建操作。

class UnionFind
{
private:
	std::vector<int> _uf;									//并查集数组
	std::unordered_map<std::string, int> _stringToMap;		//string类型转下标
	std::vector<std::string> _mapToString;					//下标转string类型

public:
	//初始化
	UnionFind(int n, std::vector<std::string>& strs)
		: _uf(n, -1)
		, _mapToString(n)
	{
		for (int i = 0; i < n; i++)
		{
			_stringToMap[strs[i]] = i;
			_mapToString[i] = strs[i];
		}
	}
};

查找一个元素在哪一个集合

        采用循环的方式,一直追溯到根节点的为止,每一个数组元素都记录着父节点的下标为止,如果说该数组元素是一个负数的话,那么就代表这个数组元素是根节点。

//查看元素在哪个集合中
int Find(int val)
{
	//如果查找的下标,超出了数组范围
	if (val >= _uf.size())
	{
		return -1;
	}

	//一直查找到根节点
	while (_uf[val] >= 0)
	{
		int parent = _uf[val];
		val = parent;
	}
	return val;
}
//按string类型进行查找 
const std::string& Find(const std::string& val)
{
	//查找映射关系
	auto it = _stringToMap.find(val);
	//没找到--返回空字符串
	if (it == _stringToMap.end())
	{
		return std::string("");
	}
	int index = Find((*it).second);
	return _mapToString[index];
}

判断两个元素是否在同一个集合

        判断两个元素是否在同一个集合,也就是判断两个元素的跟节点是不是一样的即可,所以复用Find函数代码。

    //判断两个元素是否在同一个集合
	bool IsSame(int val1, int val2)
	{
		return Find(val1) == Find(val2);
	}
	//按string类型的判断
	bool IsSame(const std::string& str1, const std::string& str2)
	{
		return Find(str1) == Find(str2);
	}

将两个集合进行合并

	//将两个集合进行合并
	void UnionSet(int val1, int val2)
	{
		//先查找两个元素的根节点
		int root1 = Find(val1);
		int root2 = Find(val2);

		//如果一样,就不用合并了
		if (root1 == root2)
			return;

		//将小的集合合并到大的集合当中
		if (std::abs(_uf[root1]) < std::abs(_uf[root2]))
		{
			std::swap(root1, root2);
		}
		//更新数组值与下标
		_uf[root1] += _uf[root2];
		_uf[root2] = root1;
	}

查询有多少组

	//查询有多少组
	int CountSet()
	{
		int count = 0;
		for (auto num : _uf)
		{
			if (num < 0)
				count++;
		}
		return count;
	}

测试

#include "UnionFind.hpp"

int main()
{
	std::vector<std::string> classmates = {
		"林晓", "陈悦", "刘阳", "张宇", "王婷",
		"李辉", "赵静", "孙峰", "周瑶", "吴俊"
	};
	//创建并查集
	UnionFind unionfind(10, classmates);

	//进行分组操作
	unionfind.UnionSet(0, 1);
	unionfind.UnionSet(0, 3);

	unionfind.UnionSet(2, 4);
	unionfind.UnionSet(2, 5);
	unionfind.UnionSet(2, 6);

	unionfind.UnionSet(7, 8);
	unionfind.UnionSet(7, 9);

	std::cout << "有多少组:" << unionfind.CountSet() << std::endl;

	//查找陈悦在哪一组
	std::cout << "陈悦的组长:" << unionfind.Find("陈悦") << std::endl;
	//查找是否在一组
	std::cout << "陈悦和张宇:" << unionfind.IsSame("陈悦", "张宇") << std::endl;
	std::cout << "陈悦和刘阳:" << unionfind.IsSame("陈悦", "刘阳") << std::endl;

	//合并
	unionfind.UnionSet(0, 2);
	std::cout << "有多少组:" << unionfind.CountSet() << std::endl;

	//查找陈悦在哪一组
	std::cout << "陈悦的组长:" << unionfind.Find("陈悦") << std::endl;
	//查找是否在一组
	std::cout << "陈悦和张宇:" << unionfind.IsSame("陈悦", "张宇") << std::endl;
	std::cout << "陈悦和刘阳:" << unionfind.IsSame("陈悦", "刘阳") << std::endl;


	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot+Vue的瑜伽课体验课预约系统【附源码】

基于SpringBootVue的瑜伽课体验课预约系统 一、系统技术说明二、运行说明三、系统的演示四、系统的核心代码演示 一、系统技术说明 框架&#xff1a;SpringbootVue 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软…

【编译器】VSCODE烧录ESP32-C3——xiaozhi智能聊天机器人固件

【编译器】VSCODE烧录ESP32-C3——xiaozhi智能聊天机器人固件 文章目录 [TOC](文章目录) 前言一、方法一&#xff1a;使用固件烧录工具1. 安装CH340驱动2. 打开FLASH_DOWNLOAD文件3. 选择芯片类型和烧录方式4. 选择烧录文件5. 参数配置 二、方法二&#xff1a;VSCODE导入工程1.…

【C++】 —— 笔试刷题day_1

为了锻炼自己写代码的思路&#xff0c;开始每日刷题&#xff0c;加油&#xff01;&#xff01;&#xff01; 第一题 数字统计 题目要求&#xff1a; ​ 给定一个范围 [L , R] 求出数字L在该区间内出现的次数。&#xff08;其中1<L<R<10000&#xff09; 算法思路&…

R语言和RStudio安装

整体还是比较简单的&#xff0c;主要是记录个流程。 官方镜像站列表R语言官网 1 安装R&#xff08;2025/3/6&#xff09; R语言官网&#xff1a;The R Project for Statistical Computing 打开之后就Hello world一下吧 配置环境变量 2 安装RStudio 下载地址&#xff1a;htt…

计算机视觉应用|自动驾驶的感知革命:多传感器融合架构的技术演进与落地实践

一、引言 自动驾驶的终极目标是实现比人类驾驶更安全、更高效的交通系统。其核心挑战在于如何让机器像人类一样感知和理解复杂环境。然而&#xff0c;人类驾驶员依赖视觉、听觉和触觉的多模态信息&#xff0c;而自动驾驶系统则需要通过传感器和算法模拟这一过程。当前&#xf…

高效自动化测试:打造Python+Requests+Pytest+Allure+YAML的接口测试框架

一、背景 在快节奏的开发周期中&#xff0c;如何确保接口质量&#xff1f;自动化测试是关键。通过构建标准化、可复用的测试框架&#xff0c;能显著提升测试效率与准确性&#xff0c;为项目质量保驾护航[1][7]。 二、目标 ✅ 核心目标&#xff1a; ● 实现快速、高效的接口测试…

速算迷你世界脚本UI

--[[ --数学速算主界面 local UI"6996144362677448610" local v"6996144362677448610_" --自定义玩家数据界面 --显示界面分类 -- --称号积分幼儿园0学前班50小学生200初中生500高中生1000大学生2000研究生5000博士生10000教授50000 local A {["主屏幕…

『PostgreSQL』 Ubuntu 系统下PG15的安装与 PGVector 配置指南

&#x1f4e3;读完这篇文章里你能收获到 &#x1f4e6; 学会如何在 Ubuntu 上安装最新的 PostgreSQL 15 数据库。&#x1f511; 掌握修改 PostgreSQL 管理员密码和配置远程连接的方法。&#x1f310; 了解如何启用 PGVector 插件&#xff0c;实现向量存储和多种距离计算。&…

关于在electron(Nodejs)中使用 Napi 的简单记录

当我们使用electron想要集成一个C SDK实现很底层的算法逻辑就有可能与C SDK进行数据通信。 Napi 应该是比较好的选择&#xff0c;因为C本身的运行速度很快&#xff0c;使用Napi也能很大程度上保证软件的兼容性、又不会阻塞C线程、还可以很简单的与C 实现数据传递。 开始使用 安…

vscode(cursor)配置python环境,含远程调试

一、本地配置 1.1 安装python插件 1.2 配置python环境 在右下角就可以切换python环境&#xff0c;太简单了&#xff01; 1.3 Debug说明 打断点直接开启&#xff01; 在debug的过程中&#xff0c;还可以输入打印中间变量或者做一些测试 二、远程连接 2.1 下载远程工具 2.2 连…

S19文件格式详解:汽车ECU软件升级中的核心镜像格式

文章目录 引言一、S19文件格式的起源与概述二、S19文件的核心结构三、S19在汽车ECU升级中的应用场景四、S19与其他格式的对比五、S19文件实例解析六、工具链支持与安全考量七、未来趋势与挑战结语引言 在汽车电子控制单元(ECU)的软件升级过程中,S19文件(也称为Motorola S-…

怎么使用数据集微调大模型LLM

怎么使用数据集微调大模型LLM 目录 怎么使用数据集微调大模型LLM项目运行后目录结构1. 导入必要的库2. 准备训练数据3. 加载模型与分词器4. 数据预处理5. 配置训练参数(CPU 专用)6. 训练与保存完整可运行代码,调试了2天,保证可用项目运行后目录结构 1. 导入必要的库 from …

深度评测DeepSeek、ChatGPT O1和谷歌Gemini AI应用开发场景 - DeepSeek性能完胜!

下面我会展示我为期一周的实验结果&#xff0c;创作不宜&#xff0c;希望大家关注我&#xff0c;以后多多互3&#xff01;前一阵我在互联网上看到很多关于DeepSeek R1的讨论&#xff0c;这个开源模型据说可以媲美&#xff0c;甚至优于像OpenAI o1这样的付费模型。 由于我在日常…

ubuntu局域网部署stable-diffusion-webui记录

需要局域网访问&#xff0c;如下设置&#xff1a; 过程记录查看源码&#xff1a; 查看源码&#xff0c;原来修改参数&#xff1a;--server-name 故启动&#xff1a; ./webui.sh --server-name0.0.0.0 安装下载记录&#xff1a; 快速下载可设置&#xff1a; export HF_ENDPOI…

数智读书笔记系列015 探索思维黑箱:《心智社会:从细胞到人工智能,人类思维的优雅解读》读书笔记

引言 《The Society of Mind》&#xff08;《心智社会》&#xff09;的作者马文・明斯基&#xff08;Marvin Minsky&#xff09;&#xff0c;是人工智能领域的先驱和奠基者之一 &#xff0c;1969 年获得图灵奖&#xff0c;被广泛认为是对人工智能领域影响最大的科学家之一。他…

2.1 Vite + Vue 3 + TS 项目脚手架深度配置

文章目录 **一、环境准备与技术选型****二、项目初始化与基础架构****三、工程化配置深度优化****四、代码规范与质量保障****五、Vue 3 深度集成****六、TypeScript 高级配置****七、第三方库集成****八、构建优化策略****九、企业级最佳实践****十、扩展配置参考****本章核心…

利用FatJar彻底解决Jar包冲突(一)

利用FatJar彻底解决Jar包冲突 序FatJar的加载与隔离⼀、 FatJar概念⼆、FatJar的加载三、FatJar的隔离四、隔离机制验证五、 FatJar的定位六、 打包注意点 序 今天整理旧电脑里的资料&#xff0c;偶然翻到大概10年前实习时写的笔记&#xff0c;之前经常遇到Java依赖冲突的问题…

C/C++蓝桥杯算法真题打卡(Day4)

一、P11041 [蓝桥杯 2024 省 Java B] 报数游戏 - 洛谷 算法代码&#xff1a; #include<bits/stdc.h> using namespace std;// 计算第 n 个满足条件的数 long long findNthNumber(long long n) {long long low 1, high 1e18; // 二分查找范围while (low < high) {lo…

DeepSeek大语言模型下几个常用术语

昨天刷B站看到复旦赵斌老师说的一句话“科幻电影里在人脑中植入芯片或许在当下无法实现&#xff0c;但当下可以借助AI人工智能实现人类第二脑”&#xff08;大概是这个意思&#xff09; &#x1f49e;更多内容&#xff0c;可关注公众号“ 一名程序媛 ”&#xff0c;我们一起从 …

快速从C过度C++(一):namespace,C++的输入和输出,缺省参数,函数重载

&#x1f4dd;前言&#xff1a; 本文章适合有一定C语言编程基础的读者浏览&#xff0c;主要介绍从C语言到C过度&#xff0c;我们首先要掌握的一些基础知识&#xff0c;以便于我们快速进入C的学习&#xff0c;为后面的学习打下基础。 这篇文章的主要内容有&#xff1a; 1&#x…