【数据结构高阶】并查集

目录

一、什么是并查集

二、并查集的原理

三、并查集的作用

四、并查集的代码实现


一、什么是并查集

在一些应用问题中,需要将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.hqwc.cn/news/517587.html

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

相关文章

如何远程访问电脑文件?

远程访问电脑文件是当今数字化时代中十分常见且实用的技术。它允许我们从任何地方的计算机或移动设备访问和操作我们的电脑中的文件。无论是远程工作、远程学习、远程协作还是方便地获得自己计算机上的重要文件&#xff0c;远程访问电脑文件都为我们提供了巨大的便利。 在远程访…

像SpringBoot一样使用Flask - 2.静态资源访问及模版

一、安装并导入 render_template 功能&#xff1a;渲染/加载模板&#xff0c;一般是html页面 参数&#xff1a;函数的第一个参数是模板的文件名&#xff0c;必填&#xff0c;后面的参数都是键值对&#xff0c;表示模板中变量对应的值&#xff0c;非必填 (不填界面也不会展示成变…

大路灯哪个牌子好?5大热卖大路灯汇总,年度首选

网上总能搜到很多和大路灯相关的话题&#xff0c;像“大路灯伤眼”、“大路灯是否有用”等很是常见。由此可见&#xff0c;大路灯虽然荣升最受欢迎的照明电器&#xff0c;但依旧备受争议。从根源上说&#xff0c;是不专业大路灯抢占市场&#xff0c;它们的基础品质得不到保障&a…

字符串标记高亮脚本

源码 #!/bin/bash # usage: # echo hhh|mark str [font_color] [background_color] # font_color and background_color is optional, default is black&whiterp_str$1 f_color30 b_color47if [ "${f_color}a" "a" ]; thenf_color30 fiif [ "${…

node的安装与介绍

安装 下载地址 node官网首页就会有两个安装选择&#xff0c;会根据当前电脑的系统自动显示对应的安装包&#xff0c;一个长期维护版&#xff08;LTS&#xff09;,一个是尝鲜版&#xff0c;记住选择LTS版本 安装指定版本下载截图 安装过程截图&#xff08;非常简单&#xff…

常用的电生理肌电信号数据合集 (EMG)

目录 Ninapro CapgMyo-DBa CSL-HDEMG EMGLAB Sleep Heart Health Study Ninapro Ninapro 是一个公开的多模式数据库&#xff0c;旨在促进人类、机器人和假肢手的机器学习研究。 10 个 Ninapro 数据集总共包括来自完整受试者和经桡动脉截肢者的 180 多个数据采集&#xff…

【MySQL】索引优化与关联查询优化

数据库调优的几个维度&#xff1a; 索引失效&#xff0c;没有充分用到索引——索引建立关联查询太多JOIN——SQL优化服务器调优以及各个参数设置——调整my.cnf数据过多——分库分表 SQL查询优化的几种方式&#xff1a; 物理查询优化&#xff1a;通过索引以及表连接方式进行…

Anaconda prompt运行打开jupyter notebook 指令出错

一、打不开jupyter notebook网页 报错如下&#xff1a; Traceback (most recent call last): File “D:\anaconda3\lib\site-packages\notebook\traittypes.py”, line 235, in _resolve_classes klass self._resolve_string(klass) File “C:\Users\DELL\AppData\Roaming\Py…

021—pandas 书单整理将同一种书整理在一起

前言 在办公自动化场景下&#xff0c;最常见的需求就是信息的整理&#xff0c;pandas 最擅长复杂数据逻辑的处理&#xff0c;能够让整理工作更加高效&#xff0c;同时不容易出错。今天的案例是将一个平铺的书单按品类进行整理&#xff0c;合并为一行。 需求: 将书按书名进行合…

盲人的智慧出行:与APP共赴无障碍之旅

在黑暗中&#xff0c;我从未感到孤单。作为一名盲人&#xff0c;我选择与一款盲人辅助软件蝙蝠避障一同踏上盲人智慧出行之旅&#xff0c;探寻生活中的无限可能。 这款软件拥有先进的障碍物识别技术&#xff0c;其基于先进的激光雷达探测&#xff0c;通过智能语音和触觉反馈&am…

夏泽网注册码

夏泽网注册码申请法:1.打开注册码申请页&#xff0c;http://nianjian.xiaze.com/getcode.php 上面会显示你的注册码链接 (是个红色的链接,不同的时间不同的人这个链接不一样)。 2.将注册码链接以超链接的方式发布在各大网站、论坛、博客&#xff08;支持各大论坛、百度空间、 网…

yduibuilder,拖拽式开发轻松高效自动生成前端代码

给大家分享一个#开源项目# &#xff1a;#yduibuilder# &#xff0c;他可以通过拖拽式的开发方式自动生成前端代码&#xff0c;这种#低代码开发工具# 已经很多了&#xff0c;没什么新鲜的&#xff1b; 但yduibuilder式通过编译的方式#生成终端代码# &#xff0c;没有预设各种功能…