热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

看图轻松理解并查集

推出一个新系列,《看图轻松理解数据结构和算法》,主要使用图片来描述常见的数据结构和算法,轻松阅读并理

推出一个新系列,《看图轻松理解数据结构和算法》,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握。本系列包括各种堆、各种队列、各种列表、各种树、各种图、各种 排序 等等几十篇的样子。

并查集

并查集(Disjoint Set)是一种用于处理不相交集合的数据结构,顾名思义,通过它可以对集合进行合并和查询操作,从而实现元素分组的管理。并查集其中一个典型应用就是在无向图中判断任意两个顶点是否连通。

集合

在数学上,集合被定义为由一个或多个确定的元素所构成的整体,简称集(Set)。集合内的对象称为该集合的元素,集合的元素都具有某种相同的性质。比如“成语大全”集合,它就包含一心一意、三心二意等等所有成语。对于集合A,如果元素a是集合A的元素,则称a属于A,记为 ,如果元素b不是集合的元素,则称b不属于A,记为 。

不相交集合

不相交集合是指两个集合没有公共的元素,反之如果两个集合有相同的元素则说明存在交集。对于两个集合A与B,如果 ,即A与B相交为空集,则称A与B不相交。比如{1, 2, 3}集合和{4, 5, 6}集合就是不相交集合。

主要操作

  • 初始化操作,把每个元素初始化为一个集合,根节点父节点都为其本身,O(n)时间复杂度。
  • 查找操作,查找某个元素所在的集合,集合由根节点表示,时间复杂度最好情况为O(1),而最坏的情况为O(n),有一些优化措施。
  • 合并操作,将两个元素所在的集合合并为一个集合,合并前需判断两个元素是否属于同一集合,只有属于不同集合才执行合并,时间复杂度最好情况为O(1),而最坏的情况为O(n)。

实现方案

并查集的实现方案有很多种,常用的实现方式是通过数组来描述树结构,从而实现并查集数据结构。其中每个集合都用一棵树来表示,树的每个节点代表集合中的一个元素,树的结构通过父指针来表示。比如下图,长度为7的数组,数组值为-1的表示自己为根节点,同时也用它代表集合,正数的值表示它的父节点元素的索引。array[1]=2,说明它的父节点是元素2,array[3]=4,说明它的父节点为元素4。

看图轻松理解并查集

初始化操作

假如有7个元素,初始化操作即是将每个元素初始化为一个集合,用长度为7的数组来表示,数组中每个元素的值都为-1,-1表示自己是根节点,下标值用于表示集合,比如0表示集合0,1表示集合1等等。

看图轻松理解并查集

合并操作

合并操作即是将两个集合合并到一起,如果要合并下标为1和2的元素,则先分别找这两个元素对应的集合,元素1的集合为1,

看图轻松理解并查集

元素2的集合为2,

看图轻松理解并查集

选择元素2作为元素1的父节点,且元素2作为新的集合。此时,元素1和元素2都属于集合2。

看图轻松理解并查集

同样地,对元素3和元素4进行合并,结果如下,此时,元素3和元素4都属于集合4。

看图轻松理解并查集

接着对元素1和元素3也进行合并,需要先分别找出元素1和元素3所在的集合,如果属于同一个集合则不必执行合并,反之如果属于不同的集合,则需要执行合并操作。从元素1开始,因为它的值为2,,说明它的父节点是元素2,

看图轻松理解并查集

所以往元素2继续查找,到达元素2后发现值为-1,说明元素2就是根节点,所以集合2即是元素1所在的集合。

看图轻松理解并查集

继续找元素3所在的集合,从元素3开始,因为它的值为4,说明它的父节点是元素4,

看图轻松理解并查集

所以往元素4继续查找,到达元素4后发现值为-1,说明元素4就是根节点,所以集合4即是元素3所在的集合。

看图轻松理解并查集

两个元素分别属于不同的集合,于是两个集合执行合并操作,原来的集合。选择元素4作为父节点,元素4作为合并后的集合。此时,集合4包含了元素1、2、3、4。

看图轻松理解并查集

查找操作

查找操作用于查找某个元素所在的集合。如果要查找元素1所在的集合,那么从元素1开始,因为元素1的值为2,所以往元素2继续找,

看图轻松理解并查集

元素2的值为4,则继续往元素4查找,

看图轻松理解并查集

元素4的值为-1,说明它是根节点,即是要找的集合,所以元素1属于集合4。

看图轻松理解并查集

路径压缩

路径压缩主要用于解决合并后树的高度增加的问题,树的高度变高的话查询效率就会变低。比如继续将元素5和元素4合并,结果树就变成如下,此时对于这棵树来说,其实元素1、2、3、4都可以直接指向元素5。

看图轻松理解并查集

于是就会在执行查询操作的过程中增加一些判断,用于压缩路径,这样当下一次查询时就可以在更矮的树中查询了。比如现在查询元素1,需要从元素1开始,通过元素2,再到元素4,最后才能找到元素5。

看图轻松理解并查集

而路径压缩会在第一次查询元素1完成后将树调整为如下图,其实逻辑很简单,就是将元素1在查找的过程中走过的元素统统都指向根节点。

看图轻松理解并查集

-------------推荐阅读------------

我的开源项目汇总(机器&深度学习、NLP、网络IO、AIML、 mysql 协议、chatbot)

为什么写《Tomcat内核设计剖析》

我的2017文章汇总——机器学习篇

我的2017文章汇总——Java及中间件

我的2017文章汇总——深度学习篇

我的2017文章汇总——JDK源码篇

我的2017文章汇总——自然语言处理篇

我的2017文章汇总——Java并发篇

跟我交流,向我提问:

看图轻松理解并查集

欢迎关注:

看图轻松理解并查集

以上所述就是小编给大家介绍的《看图轻松理解并查集》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 我们 的支持!


推荐阅读
  • 统一知识图谱学习和建议:更好地理解用户偏好
    本文介绍了一种将知识图谱纳入推荐系统的方法,以提高推荐的准确性和可解释性。与现有方法不同的是,本方法考虑了知识图谱的不完整性,并在知识图谱中传输关系信息,以更好地理解用户的偏好。通过大量实验,验证了本方法在推荐任务和知识图谱完成任务上的优势。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了在MySQL8.0中如何查看性能并解析SQL执行顺序。首先介绍了查询性能工具的开启方法,然后详细解析了SQL执行顺序中的每个步骤,包括from、on、join、where、group by、having、select distinct、union、order by和limit。同时还介绍了虚拟表的概念和生成过程。通过本文的解析,读者可以更好地理解MySQL8.0中的性能查看和SQL执行顺序。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • MySQL多表数据库操作方法及子查询详解
    本文详细介绍了MySQL数据库的多表操作方法,包括增删改和单表查询,同时还解释了子查询的概念和用法。文章通过示例和步骤说明了如何进行数据的插入、删除和更新操作,以及如何执行单表查询和使用聚合函数进行统计。对于需要对MySQL数据库进行操作的读者来说,本文是一个非常实用的参考资料。 ... [详细]
author-avatar
手机用户2502922477
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有