数据结构-并查集

并查集原理   

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

  一般可以用数组来表示并查集,数据的下标就是每个数据的编号,对应的值如果是负数,那么就代表它自成一个集合,也就是一个根结点。如图,初始值一般都是负数,也就是每个元素都自成一个集合,如果一个元素是根,那么负数的绝对值则代表这个树有多少结点;如果不是负数,那么则说明这个元素不是根,且对应的值存的是父亲结点的下标。

  实际应用中也可以通过加入哈希表来设置更多的映射关系,这样的话可以将数组的下标作为key值,然后可以存人名这些。

  所以并查集其实也是多棵树组成的森林。

用并查集表示就是

 元素之间可以合并,并且可以制定合并规则。集合与集合之间也可以合并。

 综上,我们可以知道并查集可以解决以下问题:

1.查找某个元素属于哪个集合。沿着数组表示的树形关系向上可以一直找到根。

2.查看两个元素是否属于同一个集合。可以看找到的根是否相同,以此来判断是否属于同一个集合。

3.可以将两个集合归并成一个集合。

4.求集合的个数。其实也就是根的个数,可以遍历数组,记录下标为负数的元素即是集合的个数。

并查集简单实现

#pragma once#include <vector>//可以设计成模板,加入哈希表来存放更多的映射关系class UnionFindSet
{
public:UnionFindSet(int size):_set(size, -1){}~UnionFindSet(){}size_t FindRoot(int x){int root = x;while (_set[root] >= 0)root = _set[root];  // 向上找到根while (_set[x] >= 0)    // 向上遍历,依次修改父亲的父亲结点,使其变为根结点的儿子。// 路径压缩{int parent = _set[x];_set[x] = root;x = parent;}return root;}void Union(int x1, int x2){int root1 = FindRoot(x1);int root2 = FindRoot(x2);if (abs(_set[root1]) < abs(_set[root2]))   // 小优化,每次合并都合并到结点更多的树中,可以减少层数std::swap(_set[root1], _set[root2]);if (root1 != root2)  // 如果相等说明在一个集合内,没必要合并{_set[root1] += _set[root2];_set[root2] = root1;    // 这里默认合并到root1}}int SetCount()  // 找根结点个数{size_t count = 0;for (size_t i = 0; i < _set.size(); ++i){if (_set[i] < 0)count++;}return count;}
private:std::vector<int> _set;
};void TestUFS()
{UnionFindSet u(10);u.Union(0, 6);u.Union(7, 6);u.Union(7, 8);u.Union(1, 4);u.Union(4, 9);u.Union(2, 3);u.Union(2, 5);std::cout << u.SetCount() << std::endl;
}

 另外说下压缩路径的问题,当并查集的数据非常大时,我们要找到这个元素的根,可能就需要向上找很久,有一种解决方案就是,在每次查找的时候,如果它的父亲结点不是根结点的话,就将它放到根结点的儿子结点。这样就能减少遍历的次数。

并查集虽然是一种数据结构,但是有时候又可以是一种解决问题的思路。

比如这道题,可以直接手搓一个简单的并查集,很容易就秒掉。

class Solution {
public:int findCircleNum(vector<vector<int>>& isConnected) {int n = isConnected.size();vector<int> set(n,-1);auto findRoot = [&set](int x){while(set[x] >= 0)x = set[x];return x;};for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){if(isConnected[i][j] == 1){int root1 = findRoot(i);int root2 = findRoot(j);if(root1 != root2){set[root1] += set[root2];set[root2] = root1;}}}}int count = 0;for(auto &x : set){if(x < 0)count++;}return count;}
};

 总结并查集的特点:

1.一个位置的值是负数,那么它就是树的根,这个负数的绝对值就是这个树结点的个数。

2.一个位置的值是正数,那么这个正数就是它父亲结点的下标。

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

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

相关文章

Matplotlib Figure与Axes速成:核心技能一网打尽

Matplotlib Figure与Axes速成&#xff1a;核心技能一网打尽 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333; 一、Figure&#xff08;图形&#xff09;&#x1f333;&#x1f341;1. 创建Figure&#x1f341;&#x1f341;2. 添加Axes&#…

NARF关键点提取原理简介

一、NARF2D边缘点探测的矩形平面的边长s和计算点p和上邻域的距离所用的k值 二、障碍物边缘和阴影边缘 三、NARF边缘点探测 四、NARF借助边缘点信息进行关键点检测 本人也是参考其他博主&#xff0c;以及这份英文文献写的(毕竟是英文文献&#xff0c;部分翻译肯定有些误差&…

一探Lepton Search究竟

2024年1月25日&#xff0c;阿里巴巴原技术副总裁在 Twitter 上称用不到 500 行 Python 代码实现了 AI 对话搜索引擎&#xff0c;并在27日附上了开源地址&#xff1a;https://github.com/leptonai/search_with_lepton&#xff0c;截止春节期间已经5.8K的Star。 Twitter截图 Comm…

Spring Security学习(四)——登陆认证(包括自定义登录页)

前言 和前面的文章隔了很长时间才更新Spring Security系列&#xff0c;主要原因一个是之前太忙了&#xff0c;把项目都忙完了&#xff0c;赶上春节假期&#xff0c;就慢慢研究。Spring Security的体系非常复杂&#xff0c;一口吃不了热豆腐&#xff0c;没办法速成&#xff0c;…

仰暮计划|“​他们艰苦半生,但真的希望祖国安祥,山河无恙”

自述&#xff0c;自赎 我没有在那个年代生活过&#xff0c;我一出生就是盛世中国&#xff0c;看遍了祖国的大好河山。但我没想到&#xff0c;走了这么远的路&#xff0c;吃了这么多的苦的爷爷会一直跟我说“不是国家不好&#xff0c;只是中国的钱拿去还债了&#xff0c;过了那…

代码随想录算法训练营Day56|583. 两个字符串的删除操作、72. 编辑距离

目录 583. 两个字符串的删除操作 前言 思路 算法实现 法二 72. 编辑距离 前言 思路 算法实现 总结 583. 两个字符串的删除操作 题目链接 文章链接 前言 本题与上一题不同的子序列相比&#xff0c;变化就是两个字符串都可以进行删除操作了。 思路 利用动规五部曲进…

【AI视野·今日Robot 机器人论文速览 第七十九期】Thu, 18 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Thu, 18 Jan 2024 Totally 43 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers CognitiveDog: Large Multimodal Model Based System to Translate Vision and Language into Action of Quadruped Robot Aut…

哈希表 ?

哈希表 首先什么是 哈希表&#xff0c;哈希表&#xff08;英文名字为Hash table&#xff0c;国内也有一些算法书籍翻译为散列表&#xff0c;大家看到这两个名称知道都是指hash table就可以了&#xff09;。 哈希表是根据关键码的值而直接进行访问的数据结构。 这么这官方的解释…

【C++初阶:类和对象(下篇)】初始化列表 | static成员 | 友元

目录 一、构造函数构造函数体赋值&#x1f43e;初始化列表&#x1f43e;&#x1f4a6; explicit关键字 二、static成员&#x1f43e;概念**&#x1f4a6; 关于静态的特性** 三、友元&#x1f4a6; **友元函数**&#x1f4a6; **友元类** **四、内部类** 一、构造函数 构造函数…

VM和Linux安装

VM和Linux安装 一、下载VM 1.官网地址&#xff1a;https://www.vmware.com/cn.html 2.其他地址&#xff1a;http://ww7.nocmd.com/windows/740.html 许可证这个&#xff0c;大家可以自己上网搜索&#xff0c;很容易就搜索到就可以使用了 上面内容就是安装VM的步骤 安…

30. 异常

异常 1. 概述2. Throwable 方法2.1 概述2.2 代码示例 3. 异常分类4. 异常处理方式4.1 JVM默认处理异常4.2 自己处理&#xff08;捕获异常&#xff09;try...catch4.2.1 概述4.2.2 灵魂四问 4.3 抛出处理(throw和throws) 5. 自定义异常5.1 概述5.2 代码示例 6. 异常注意事项 文章…

代码随想录算法训练营第三十一天 |基础知识,455.分发饼干,376.摆动序列,53.最大子序和(已补充)

基础知识&#xff1a; 题目分类大纲如下&#xff1a; #算法公开课 《代码随想录》算法视频公开课(opens new window)&#xff1a;贪心算法理论基础&#xff01;(opens new window),相信结合视频再看本篇题解&#xff0c;更有助于大家对本题的理解。 #什么是贪心 贪心的本质…

python分离字符串 2022年12月青少年电子学会等级考试 中小学生python编程等级考试二级真题答案解析

目录 python分离字符串 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python分离字符串 2022年12月 python编程等级考试级编程题 一、题目要…

【数据结构】链表OJ面试题5《链表的深度拷贝》(题库+解析)

1.前言 前五题在这http://t.csdnimg.cn/UeggB 后三题在这http://t.csdnimg.cn/gbohQ 给定一个链表&#xff0c;判断链表中是否有环。http://t.csdnimg.cn/Rcdyc 给定一个链表&#xff0c;返回链表开始入环的第一个结点。 如果链表无环&#xff0c;则返回 NULLhttp://t.cs…

1 月 NFT 市场动态:Polygon 增长,Mooar 崛起,TinFun 掀起文化浪潮

作者&#xff1a;stellafootprint.network 数据源&#xff1a;NFT Research - Footprint Analytics 2024 年 1 月&#xff0c;加密货币与 NFT 市场迎来了重要的转折点&#xff0c;其中美国首批现货比特币 ETF 的亮相尤为引人注目&#xff0c;这一金融一体化的里程碑事件吸引了…

论文阅读-One for All : 动态多租户边缘云平台的统一工作负载预测

论文名称&#xff1a;One for All: Unified Workload Prediction for Dynamic Multi-tenant Edge Cloud Platforms 摘要 多租户边缘云平台中的工作负载预测对于高效的应用部署和资源供给至关重要。然而&#xff0c;在多租户边缘云平台中&#xff0c;异构的应用模式、可变的基…

【C/C++】2024春晚刘谦春晚魔术步骤模拟+暴力破解

在这个特别的除夕夜&#xff0c;我们不仅享受了与家人的温馨团聚&#xff0c;还被电视机前的春节联欢晚会深深吸引。特别是&#xff0c;魔术师刘谦的精彩表演&#xff0c;为我们带来了一场视觉和心灵的盛宴。在我的博客“【C/C】2024春晚刘谦春晚魔术步骤模拟暴力破解”中&…

c#cad 创建-直线(五)

运行环境 vs2022 c# cad2016 调试成功 一、代码说明 这段代码是用于在AutoCAD中创建一条直线。首先获取当前活动文档和数据库的引用&#xff0c;然后创建一个编辑器对象用于提示用户输入。接下来&#xff0c;在一个事务中获取模型空间的块表记录&#xff0c;并定义直线的长度…

Hive的Join连接、谓词下推

前言 Hive-3.1.2版本支持6种join语法。分别是&#xff1a;inner join&#xff08;内连接&#xff09;、left join&#xff08;左连接&#xff09;、right join&#xff08;右连接&#xff09;、full outer join&#xff08;全外连接&#xff09;、left semi join&#xff08;左…

docker磁盘不足!已解决~

目录 &#x1f35f;1.查看docker镜像目录 &#x1f9c2;2.停止docker服务 &#x1f953;3.创建新的目录 &#x1f32d;4.迁移目录 &#x1f37f;5.编辑迁移的目录 &#x1f95e;6.重新加载docker &#x1f354;7.检擦docker新目录 &#x1f373;8.删掉旧目录 1.查看doc…