谈一谈并查集QAQ(上)

最近几日理了理学过的很多oi知识。。。发现不知不觉就有很多的知识忘记了。。。

在聊聊并查集的时候顺便当作巩固吧。。。。

什么是并查集呢?

( Union Find Set ) 是一种用于处理分离集合的抽象数据结构类型。

具体一点:

  当我们给出两个元素的一个无序对(a,b)时,需要快速合并a和b所在的集合,这期间需要反复查找出某元素所在的集合,“并”、“查”和“集”三字由此而来。也就是说,并查集的作用是动态地维护和处理集合元素之间的复杂关系。

  在并查集中,n个不同的元素被分为若干组,每组是一个集合,这种集合就叫做“分离集合”。并查集支持查找一个元素所属的集合以及两个元素各自所属集合的合并操作。

例如,我们有这样一个问题:

  一个城镇里居住着n个市民,已知一些人互为朋友,而且朋友的朋友也是朋友,也就是说,如果A和B是朋友,C和B是朋友,则A和C也是朋友,请你根据给出的若干组朋友关系,求出最大的一个朋友圈的人数。

  这就有了并查集的用武之地了,一开始我们把所有人都各自放在一个集合中,然后根据依次给出的朋友关系,查找判断两个人是否属于同一个集合(是否已经是朋友),如果不在同一个集合,则将这两个集合合并成一个集合(行成一个朋友圈),最后看哪个集合的元素最多并输出个数即可。

然而并查集有什么主要操作呢?

  使用并查集首先要记录一组分离的动态集合S = {S1,S2,···,Sn},每个集合还要设置一个代表来识别,代表只是要选择该集合中的某个元素即可,哪一个元素被选作代表是无所谓的,重要的是,如果请求某一动态集合的代表两次,且在两次请求间不修改集合,则两次得到的答案应该是相同的。并查集主要有三种操作:初始化、查找与合并。

  (1)初始化:make-set(x)

  建立一个新的集合,其仅有的成员是x(同时就是代表)。由于各集合是分离的,所以要求x在没有其他集合中出现过。使用并查集前都需要执行一次初始化操作,无论采用何种实现方式,其时间复杂度都是O(n)。

  (2)查找:find-set(x)

  查找一个元素所在的集合,本操作返回一个包含x的集合的代表。查找是并查集的核心操作,也是优化并查集效率的重点。

  (3)合并:merge(x,y)

  将包含x和y的动态集合(假设为Sx和Sy)合并成一个新的集合S,本操作返回集合Sx∪Sy的代表。一般来说,在不同的实现中通常以Sx或者Sy的代表作为新集合的代表。合并之前一般要先判断两个元素是否属于同一集合,这可以通过查找操作来实现。

终于到了并查集的实现了!!

  并查集可以采用数组、链表和树三种数据结构来实现,选择不同的实现方式会给查找操作和合并操作的效率带来很大的差别。

并查集的数组实现:

  实现并查集的最简单的方法就是用数组记录每个元素所属集合的编号,A[i] = j 表示元素i属于第j 类集合,初始化A[i] = i。查找元素所属的集合时,只需读出数组中记录的该元素所属集合的编号A[i],时间复杂度为O(1)。合并两个元素各自所属集合时,需要将数组中属于其中一个集合的元素所对应的数组元素值全部更新为另一个集合的编号值,时间复杂度为O(n)。所以用数组实现并查集是最简单的方法,而且容易理解,实际使用较多。但是,合并操作的代价太高,在最坏的情况下,所有集合合并成一个集合的总代价会达到O(n2)。

并查集的链表实现:

  用链表实现并查集也是一种很常见的手段。每个分离集合对应一个链表,链表有一个表头,每个元素有一个指针指向表头,表明了它所属集合的类别,另设一个指针指向它的下一个元素,同时为了方便实现,再设一个指针last表示链表的表尾。

  因为并查集问题处理的对象往往都是连续的整数,所以一般选择用静态数组来模拟链表,用下标对应集合的元素。具体数据结构体定义如下qwq:

 

struct node{int head,next,last;
}S[maxn];

  

  此时,初始化和查找操作的实现就很简单了。

 

make-set(x){S[x].head = x;S[x].next = 0;
}
find-set(x){return S[x].head;
}

 

  对于合并操作,我们先假设merge(x,y)的参数是有序的,是把y所属的集合合并到x所在的集合。首先执行查找操作,当出现find-set(x)≠ find-set(y)时,直接将y的表头接到x的表尾,同时将y所在集合的所有元素head值设为find-set(x),x的表尾也设为y的表尾。需要注意的是,last指针只要在表头结点中记录即可,因为每一次查找到find-set(x)都可以得到表头元素,而链表中其他元素记录last值是毫无意义的。

  考虑到输入数据的特殊性,根据以上合并方法,我们总是把y接到x后面,如果y所在的集合非常大,每次复制的代价就会非常高,比如输入数据形如:(2,1),(3,1),(4,1),·····,(n,1),显然y所在的集合就会越来越庞大,此时时间复杂度就会达到O(n2)。不过,我们可以很快滴想到一个优化方法:不妨比较x和y所在集合的大小,把较短的链表接在较长的链表尾部,这样效果是一样的,但时间效率肯定不比原来差。具体实现时可以在node里多设一个number域,用来记录此条链表中成员的个数。显然,number记录在表头元素中即可。将两个链表合并的时候,只需要将链表的number域相加,因此维护起来是非常方便的。这种快速实现的方法称为“加权启发式”合并,这里的权就是指number域。假设有n个元素,则可以证明这种方法合并操作的总次数不超过nlog2n次。

 

merge(x,y){x = find-set(x);y = find-set(y);if(x.number > y.number)merge(x,y);merge(y,x);
}

  

  以上是并查集的两种实现方法qwq。然而最最最重要以及实用的是并查集的树实现。我会在  谈一谈并查集QAQ(下) 中仔细讲解qwq。

 

  

 

转载于:https://www.cnblogs.com/excellent-zzy/p/10686911.html

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

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

相关文章

vue的双向绑定原理及实现

前言 使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,所以这次特意花了几晚时间查阅资料和阅读相关源码,自己也实现一个简单版vue的双向绑定版本,先上个成果图来吸引各位&a…

python后端将svc文件数据读入数据库具体实现

如何用python将svc文件的数据读入到MySQL数据库里,在此直接上代码了,感兴趣的朋友可以贴代码测试: import pandas as pd import os from sqlalchemy import create_engine # 初始化数据库连接,使用pymysql模块 # MySQL的用户&…

作业——8

这个作业属于哪个课程C语言程序设计Ⅱ这个作业的要求在哪里C语言作业评价标准我在这个课程的目标是指针与字符串这个作业在哪个具体方面帮助我实现目标使用指针与字符串参考文献指针和字符串(基础知识)第七周作业 一 1 、使用函数删除字符串中的字符 输入…

Vue实现组件props双向绑定解决方案

注意: 子组件不能直接修改prop过来的数据,会报错 方案一: 用data对象中创建一个props属性的副本 watch props属性 赋予data副本 来同步组件外对props的修改 watch data副本,emit一个函数 通知到组件外 HelloWorld组件代码如下…

统计词频问题

adict{} xinput().lower() #把单词大写字母改为小写字母 for i in x:if i in [,,.,"",",!]:xx[:x.index(i)]x[x.index(i)1:] #把句子中的非字母字符用切片操作删掉 asetset(x.split( )) #集合的好处在于不重复 alstx.split( ) for n in aset:tempdict{n:alst.…

正则表达式常用函数

<?php //preg_match("正则表达式","字符串")用于在字符串中查找匹配项 $email "987044391qq.com"; if (preg_match("/^([a-zA-Z0-9])([.a-zA-Z0-9_-])*([.a-zA-Z0-9_-])([.a-zA-Z0-9_-])([.a-zA-Z0-9_-])$/",$email)){ echo 匹…

利用js的闭包原理做对象封装及调用方法

创建一个js文件&#xff0c;名为testClosure.js&#xff1a; ? 1 2 3 4 5 6 7 8 9 (function () { function a() { alert(i am a); } outFunc function () { a(); } })(); 这里不论写多少个function,a b c d ...外面都调用不到&#xff0c;包括这里面va…

Flask系列06--(中间件)Flask的特殊装饰器 before_request,after_request, errorhandler

一.使用 Flask中的特殊装饰器(中间件)方法常用的有三个 app.before_request # 在请求进入视图函数之前app.after_request # 在请求结束视图函数之后 响应返回客户端之前app.errorhandler(404) # 重定义错误信息before_request def func():passafter_request def func(ret): # …

Flask 中内置的 Session

Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from flask import session app Flask(__name__) app.secret_key "DragonFire" secret_key 实际上是用来加密字符串的,如果…

CSS像素、物理像素、逻辑像素、设备像素比、PPI、Viewport

最近看了很多这方面的文章&#xff0c;能搜到的基本看了个遍&#xff0c;但感觉还是似懂非懂&#xff0c;知道这个东西&#xff0c;很难说出这是个什么东西&#xff0c;先整理一些概念&#xff0c;慢慢消化&#xff0c;以后慢慢探索其中的原因。 1、PX(CSS pixels) 1.1 定义 …

【转】10条你不可不知的css规则

10条你不可不知的css规则 Posted on 2006-12-20 10:33 雨中太阳 阅读(343) 评论(1) 编辑 收藏 &#xff1a;【译】10条你不可不知的css规则正文&#xff1a; Published December 6th, 2004 in CssStaff Tags: No Tags. 原文地址&#xff1a;Ten CSS Tricks You May not Know k…

Python 面向对象【1】

对象 属性 方法面向对象特征&#xff1a;分装 继承 多态【不同对象对同一方法响应不同行动】类定义class xxx:........类对象类对象支持两种操作&#xff1a;属性引用和实例化 属性引用 使用和 Python 中所有的属性引用一样的标准语法&#xff1a;类对象名.属性名 类对象创建…

【前端面试】HTML5+CSS3初级面试1

最近刚好在看前端的面试&#xff0c;把看到的内容总结一下&#xff0c;方便大家一起学习。 1、简单说一下对HTML5CSS3的了解。 HTML5和CSS3不仅是两项新的Web技术标准&#xff0c;而且代表了下一代HTML和CSS技术。其未来的发展前景已经可以预见&#xff0c;那就是HTML5必将被越…

福大软工 · 第八次作业(课堂实战)- 项目UML设计(团队)

1、队伍信息&#xff1a; 队伍名称&#xff1a;彳艮彳亍团队 学号名本次作业博客链接031602219奇豪(队长)https://www.cnblogs.com/S031602219/p/9822576.html041602209毓明http://www.cnblogs.com/mingsonic/p/9820702.html041602204水源http://www.cnblogs.com/littlenorthwe…

【转发】实现yolo3模型训练自己的数据集总结

原文链接&#xff1a;实现yolo3模型训练自己的数据集总结 经过两天的努力&#xff0c;借鉴网上众多博客&#xff0c;在自己电脑上实现了使用yolo3模型训练自己的数据集并进行测试图片。本文主要是我根据下面参考文章一步步实施过程的总结&#xff0c;可能没参考文章中那么详细&…

详解 vue-cli 的打包配置文件代码(带注释)

一、前言 对于webpack基础不好&#xff0c;node指令不通的童鞋。估计对自己搭建Vue、react脚手架是相当头疼的&#xff0c;有种无从下手的感觉。然而&#xff0c;从头看这2块&#xff0c;耗时太长&#xff0c;而且说实话得练才行&#xff0c;不练练手看不明白。那大多数人就采取…

NoClassDefFoundError

技术之路最公平也最残酷的原因是&#xff1a;没有捷径&#xff0c;需要日积月累的积累&#xff0c;以及对技术持久的热情。NoClassDefFoundError这个错误一般就两种情况&#xff1a;1、没有引入相应的jar包2、两个jar包中都有这个class&#xff0c;无法确认是引用的哪一个&…

【记录一下】从0到1 我的python开发之路

请设计实现一个商城系统&#xff0c;商城主要提供两个功能&#xff1a;商品管理、会员管理。商品管理&#xff1a;- 查看商品列表 - 根据关键字搜索指定商品 - 录入商品会员管理&#xff1a;【无需开发&#xff0c;如选择则提示此功能不可用&#xff0c;正在开发中&#xff0c;…

Python10/22--面向对象编程/类与对象/init函数

类&#xff1a; 语法: class关键字 类名# 类名规范 大写开头 驼峰命名法class SHOldboyStudent: # 描述该类对象的特征 school "上海Oldboy" name "矮根" age 68 gender "unknown" # 在定义阶段 # 只要包含该类的py被…

Django Form和ModelForm组件

Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时&#xff0c;都会写一些获取用户输入的标签并且用form标签把它们包起来。 与此同时我们在好多场景下都需要对用户的输入做校验&#xff0c;比如校验用户是否输入&#xff0c;输入的长度和格式等正不正确。如果用户输…