并查集+基础知识点详解

并查集概念

并查集单看名字大家也能猜到这个算法的作用,是用来对集合进行合并和查找操作

并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。——来自百度百科

就是将原本不一样的集合,但是由于某种关系有了联系,把他合并成同一个集合,就是实现一个这样的功能。

基本操作

并查集是一种非常简单的数据结构,(我是说它的算法实现简单)它主要涉及两个基本操作,分别为:
A.合并: 合并两个不相交集合
B.查找: 去判断两个元素是否属于同一个集合
接下来,我会用并查集的图形解释来看下如何实现这两个基本操作。
1.可以看到这里有六个小球,他们代表六个不一样的元素,用数组来表示他们,给他们附上值,来代表不一样的集合
在这里插入图片描述

2.现在我来给他们一些联系,然后可以根据联系进行集合的一个合并,随机得到一个树状结构
在这里插入图片描述
只要是能通过关系串联起来的,不管是直接联系还是间接联系,元素通过两两之间的关系串联起来,把他们都归到同一个集合。那么如何判断两个元素是否属于一个集合呢?

我们可以在每个集合内确定一个祖宗节点,你们可以认为是一个特殊点,作为参照。这样,两个集合只要互相确认自己的祖宗节点是不是同一个,就可以确定关系了。

但是还有问题啊,目前我们只知道直接的联系,那么我们就需要对集合进行操作,形成树状结构,祖宗节点就是根节点,下面分别是二级、三级…。每个人只要记住自己的上级是谁就行了。那么判断是否属于同一个集合,只要一层层向上查找,直到最高层,就可以在短时间内确定了。由于我们关心的只是两个元素是否在同一个集合的,至于他们是如何通过关系相关联的,以及每个圈子内部的结构是怎样的,甚至祖宗节点是谁,都不重要了,就可以随机确定上下级关系
3.我们最终经过处理,实现的是如图所示
在这里插入图片描述

接下来是对代码实现的一个讲解

一般来说,一个并查集代码实现对应三个重要步骤:初始化+查找根结点函数+合并集合函数

【初始化】

这个集合的类别pre(其实就是一个指针,用来指示这个集合属于那一类,合并过后的集合,他们的pre指向的最终值一定是相同的)
初始化的时候,每一个集合的pre都是这个集合自己的标号。没有跟它同类的集合,那么这个集合的源头只能是自己了。

int pre[max];   //集合index的类别,或者用parent表示
//初始化集合
void init()
{    for(int i=1;i<=n;i++)pre[i]=i;   //一个集合的pre都是这个集合自己的标号。没有跟它同类的集合,那么这个集合的源头只能是自己了。 
}

【查找函数】

就是找到pre指针的源头,可以把函数命名为find,如果集合的pre等于集合的编号(即还没有被合并或者没有同类),那么自然返回自身编号。 如果不同(即经过合并操作后指针指向了源头(合并后选出的rank高的集合))那么就可以调用递归函数,如下面的代码:

//查找集合i(一个元素是一个集合)的源头(递归实现)
int Find(int i)
{//如果集合i的父亲是自己,说明自己就是源头,返回自己的标号if(pre[i]==i)return pre[i];//否则查找集合i的父亲的源头return  Find(pre[i]);       
}

递归,这个已经讲过很多次,这里就不再多讲,大家可以结合浏览器的后退功能,如果你想追溯源头,你就一直回溯,就能找到。

【合并】

将两个元素所在的集合合并为一个集合。
通常来说,合并之前,应先判断两个元素是否属于同一集合,这可用上面的"查找"操作实现。那么我们如何合并两个不相交集合(Union(x,y))
合并操作很简单:先设置一个数组pre[x],表示x的“父亲”的编号。那么,合并两个不相交集合的方法就是,找到其中一个集合祖宗节点,将另外一个集合的祖宗节点的父亲指向它。

int gets(int a,int b){int x=Find(a);int y=Find(b);if(x!=y)pre[y]=x;}

算法描述总结

关键特征:
①用集合中的某个元素来代表这个集合~~,该元素称为集合的代表元;~~
②构成了一个以代表元素为根的树形结构;
③对于每一个元素 pre[x]指向x在树形结构上的父亲节点。如果x是根节点,则令pre[x] = x;
④对于查找操作,假设需要确定x所在的的集合,也就是确定集合的代表元。可以沿着pre[x]不断在树形结构中向上移动,直到到达根节点。
判断两个元素是否属于同一集合,只需要看他们的代表元是否相同即可。
用途:
1、维护无向图的连通性。支持判断两个点是否在同一连通块内,和判断增加一条边是否会产生环。
2、用在求解最小生成树的Kruskal算法里。
如果还有哪里我讲的不清楚,或是有疑问,欢迎私聊我,我会为你们解答。

贴上其他博客讲解并查集的1 2 3 4

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

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

相关文章

[C++11]move资源的转移

从实现上讲&#xff0c;std::move 基本等同于一个类型转换&#xff1a;static_cast<T&&>(lvalue);&#xff0c;函数原型如下: template<class _Ty> _NODISCARD constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) _NOEXCEPT { …

基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型

上一篇文章使用自定义仓储完成了简单的增删改查案例&#xff0c;有心的同学可以看出&#xff0c;我们的返回参数一塌糊涂&#xff0c;显得很不友好。在实际开发过程中&#xff0c;每个公司可能不尽相同&#xff0c;但都大同小异&#xff0c;我们的返回数据都是包裹在一个公共的…

奔小康赚大钱 HDU - 2255( 二分图匹配KM算法详解)

题目 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革&#xff1a;重新分配房子。 这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住&#xff08;如果有老百姓没房子住的话&#xff0c;容易引起不安定因素&…

记一次排查线上程序内存的忽高忽低,又是大集合惹祸了

一&#xff1a;背景1. 讲故事昨天继续还技术债&#xff0c;优化一轮后的程序拉到线上后内存继续忽高忽低&#xff0c;低的时候20G&#xff0c;高的时候30G&#xff0c;过了一会又下降了几个G&#xff0c;毫无疑问&#xff0c;程序中有什么集合或者什么操作占用了大量内存&#…

[C++11]forward完美转发

// 函数原型 template <class T> T&& forward (typename remove_reference<T>::type& t) noexcept; template <class T> T&& forward (typename remove_reference<T>::type&& t) noexcept;// 精简之后的样子 std::forward…

Pipe HDU - 2150(判断线段相交+向量叉乘线代详解)

题目&#xff1a; 经过激烈的争夺&#xff0c;Lele终于把那块地从Yueyue的手里抢了回来。接下来&#xff0c;Lele要开始建造他的灌溉系统。 通过咨询Lele的好友——化学系的TT&#xff0c;Lele决定在田里挖出N条沟渠&#xff0c;每条沟渠输送一种肥料。 每条沟渠可以看作是一…

win7如何将计算机移至桌面,如何将win7电脑桌面的文件转移到其他盘中?

想必很多朋友都和小编一样&#xff0c;是一个嫌麻烦的人&#xff0c;是一个不怎么爱收拾的人吧?这种人有一个通病&#xff0c;那就是喜欢将一些重要的文件放置在win7 64位纯净版下载的桌面上&#xff0c;这样的话&#xff0c;不仅容易找到&#xff0c;而且方便使用&#xff0c…

凸包算法知识总结

首先&#xff0c;什么是凸包&#xff1f; 假设平面上有p0~p12共13个点&#xff0c;过某些点作一个多边形&#xff0c;使这个多边形能把所有点都“包”起来。当这个多边形是凸多边形的时候&#xff0c;我们就叫它“凸包”。 处理何种问题&#xff1a;凸包可以看成在木板上钉许多…

[C++11]shared_ptr使用的注意事项(内存被重复析构,内存泄漏问题)

shared_ptr使用的注意事项: 1.不能使用一个原始地址初始化多个共享智能指针 2.函数不能返回管理了this的共享智能指针对象 3.共享智能指针不能循环引用 不能使用一个原始地址初始化多个共享智能指针 代码如下: #include <iostream> #include <memory> using name…

一文解读使用WinDbg排查iis 中CPU占用高的站点问题

一、概述在Window服务器部署程序后&#xff0c;可能因为代码的不合理或者其他各种各样的问题&#xff0c;会导致CPU暴增&#xff0c;甚至达到100%等情况&#xff0c;严重危及到服务器的稳定以及系统稳定&#xff0c;但是一般来说对于已发布的程序&#xff0c;没法即时看到出问题…

Power Network POJ - 1459(EK算法模板+详解)

题意&#xff1a; 总共有a个节点&#xff0c;其中有发电站b个、用户c个和调度器a-b-c个三种节点&#xff0c;每个发电站有一个最大发电量&#xff0c;每个用户有个最大接受电量&#xff0c;现在有d条有向边&#xff0c;边有一个最大的流量代表&#xff0c;最多可以流出这么多电…

[C++11]shared_ptr共享智能指针的初始化与使用

使用智能指针需要添加头文件: 代码如下: #include <memory>shared_ptr使用的注意事项: 1.不能使用一个原始地址初始化多个共享智能指针 2.函数不能返回管理了this的共享智能指针对象 3.共享智能指针不能循环引用 初始化: 1.通过构造函数初始化 代码如下: std::shar…

人在职场,表达似水

最近几天集中在和部门内的小伙伴做1&#xff1a;1Talk。发现有不少人表达能力真的不是很好&#xff0c;而且水平长期停滞不前。现场与他们分享了一些我的经验&#xff0c;趁热打铁也想在这里分享给大家。表达能力不好本身就是做技术的人身上的一个常见标签。如果仅仅是标签也就…

[C++11]弱引用智能指针weak_ptr初始化和相关的操作函数

弱引用智能指针 std::weak_ptr 可以看做是 shared_ptr 的助手&#xff0c;它不管理 shared_ptr 内部的指针。std::weak_ptr 没有重载操作符 * 和 ->&#xff0c;因为它不共享指针&#xff0c;不能操作资源&#xff0c;所以它的构造不会增加引用计数&#xff0c;析构也不会减…

电子科技大学计算机网络技术专业,计算机专业前景如何?最强十大高校有哪些?电子科大排名多少?...

近几年计算机专业以及与计算机相关的专业可谓是火的不能再火&#xff0c;越来越多的考生在高考时选择了计算机专业或者与计算机相关的专业&#xff01;事实也是如此&#xff0c;随着科技的进步&#xff0c;信息技术的迅猛发展&#xff0c;特别是计算机技术的发展&#xff0c;以…

写一个简版 asp.net core

动手写一个简版 asp.net coreIntro之前看到过蒋金楠老师的一篇 200 行代码带你了解 asp.net core 框架&#xff0c;最近参考蒋老师和 Edison 的文章和代码&#xff0c;结合自己对 asp.net core 的理解 &#xff0c;最近自己写了一个 MiniAspNetCore &#xff0c;写篇文章总结一…

[C++11]独占的智能指针unique_ptr的删除器

unique_ptr 指定删除器和 shared_ptr 指定删除器是有区别的&#xff0c;unique_ptr 指定删除器的时候需要确定删除器的类型&#xff0c;所以不能像 shared_ptr 那样直接指定删除器&#xff0c;举例说明&#xff1a; 代码如下: #include <iostream> #include <memory…

如何在Windows上使用Git创建一个可执行脚本?

长话短说&#xff0c;今天介绍如何在windows上使用Git上创建一个可执行的shell脚本。“首先我们要知道windows上Git默认添加的文件权限是:-rw-r--r--(对应权限值是644)&#xff0c;而通常创建的shell脚本都希望天然可执行&#xff0c;故有必要在Windows上使用Git管理shell脚本时…

[C++11]共享智能指针shared_ptr指定删除器

当智能指针管理的内存对应的引用计数变为 0 的时候&#xff0c;这块内存就会被智能指针析构掉了。另外&#xff0c;我们在初始化智能指针的时候也可以自己指定删除动作&#xff0c;这个删除操作对应的函数被称之为删除器&#xff0c;这个删除器函数本质是一个回调函数&#xff…