不相交集合的数据结构

一、不相交集合的操作

        不相交集合的数据结构维护了一组不相交动态集的集合 S=\left \{ S1,S2,S3.......\right \},用集合中的某个成员作为代表标识集合。

        集合在没有修改的情况下每次访问代表得到的答案是相同的,此外在其它一些应用中,可能按照规定选择集合的代表,例如选择每个集合中关键字最小的元素作为代表。

设 x 为一个对象,对不相交集合数据结构的操作:

        1.MAKE-SET(x):建立一个新集合,唯一元素就是 x ,由于各个集合是不相交的,x 不会出现在其他的集合中       

        2.FIND-SET(x):返回一个指针,指向包含 x (唯一)的集合代表                                                          如果已经有指针指向 x ,无需再在数据结构中搜索 x 

        3.UNION(x,y):将包含 x 和 y 的两个动态集合(表示为 Sx 和 Sy)合并成一个新的集合,即两个集合的并集。 并集中的任何一个元素都可以作为代表(通常实现为 Sx 或 Sy 元素的代表)。由于要求各个元素不相交,合并后需要删除 Sx 和 Sy 集合,通常将一个集合并入另一个集合作为删除操作当共有n个元素时,最多执行 n-1 次UNION操作。

        不相交集合的应用——确定无向图的连通分量

   在开始时,需要通过 MAKE-SET(v) 操作将每个节点 v 都放入子集的集合中,再对处理的边(u,v)将包含 u 和 v 的集合合并(前提是两个集合本身不相交,即集合代表不相同)。

        判断两个节点是否在同一个集合中,即所属集合的集合代表不相同

                FIND-SET(x) ! = FIND-SET(y)

            Edge processed:对两点之间边处理顺序 

二、不相交集合的链表表示

        1.相关概念

        每个集合用一个链表来表示,链表的第一个节点就是代表每个集合对象 set 包含 head 指针 和 tail 指针分别指向链表中的第一个节点和最后一个节点。

        链表中的每个节点都包含一个集合成员(元素),指向链表中下一个节点的指针,指回到集合对象的指针

        2.不相交集合的链表操作

        ① MAKE-SET(x) :

                  创建一个只有 x 节点的新的链表     时间开销 O(1)

        ② FIND-SET (x):

             沿着 x 对象的返回指针返回到集合对象,然后返回 head 指针指向的节点。 时间开销 O(1)

        ③ UNION(x,y):

                1.将包含 y 的链表添加到包含 x 的链表

                2.将包含 x 的链表的代表 作为 y 中节点的代表

                3.更新包含 y 链表中各个元素的代表指针    包含 n 个操作的序列可能会花费O(n^{2})时间

        合并的简单实现:

                将长链表插入到短链表之中 总开销是O(n^{2})   平均开销是Θ(n)        

       3.一种加权合并的启发式策略

        将链表的长度作为权值并维护链表长度,合并时将短的链表拼接到长的链表末尾

        定理:使用不相交集合的链表表示和加权合并的启发式策略,一个具有 m 个 MAKE-SET FIND-SET 和 UNION 操作的序列 (其中 n 个 为 MAKE-SET操作),需要的时间为        O(m+nlogn)

三、不相交集合森林

        在不相交集合实现中,使用有根树来表示集合,树中的每个节点包含一个成员,每棵树代表一个集合。 在不相交集合森林中,每个成员仅指向他的父节点(根节点指向其自己),并且每棵树的根是集合的代表。

        1.不相交集合森林的操作

        ①MAKE-SET : 建立一个包含节点 x 的新树,并且其的父节点指向自己(根节点)

void MAKE-SET(int x)
{x.p=x;x.rank=0;return ;
}

        ②FIND-SET(x) :返回 x 所在树的集合代表(根节点)。

        FIND-SET(x) 用于鉴定集合是否包含元素 x 

        FIND-SET (x) 和 FIND-SET (y) 返回相同的值,当且仅当元素 x 和 y 同属一个集合

int FIND-SET (int x)
{ if (x≠x.p)    // x不是根 x.p=FIND-SET(x.p);return x.p;
}

        ③ UNION(x,y) :合并包含 x 和 y 的集合的树

        若两棵树的根的秩不相同,则将具有较小秩的根点的父指针指向具有较大秩的根结点;

        若两棵树的根的秩相同,则任意选择两个根中的一个作为父结点,并将它的秩加一。

        一颗二项树的节点的秩(rank)等于它的儿子节点的个数,

void UNION (int x,int y)
{ LINK(FIND-SET(x), FIND-SET(y)); 
}
void LINK(int x,int y)
{if(x.rank>y.rank)y.p=x;else x.p=y;if(x.rank==y.rank)y.rank=y.rank+1;return ;
}

        ④ 节点数据结构

        使用包含两个字段的结点: element and parent

        使用数组 table[] ,其中 table[x] 是一个指向元素 x 的指针 为了执行 FIND-SET (x) 操作, 从 table[i] 标明的结点开始,顺着parent 字段,直到找到结点,使得 parent 字段值为 null 返回根节点的 element

        2.两条启发式规则(改进运行时间)

        ① 按秩合并:执行 UNION 操作时,通过权重或者树高操作

        树的根节点必须要么记录树高,要么记录元素个数.

        当使用树高规则时,仅当两棵树高度相等时,树高会增加.

        当使用权重规则时,新树的权重是两个子树的权重之和.

        树高规则:将树高小的树作为作为树高大的树的子树

         权重规则:包含元素少的那棵树作为元素多的子树

        ②路径压缩 :缩短查找根节点过程中的路径

        在FIND-SET操作中,可以使查找路径中的每个结点直接指向根

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

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

相关文章

如何使用JMeter测试导入接口/导出接口?

🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号:互联网杂货铺,回复1 ,免费获取软件测试全套资料,资料在手,涨薪更快 今天上班,被开发问了一个问题:JM…

设计非递归算法,编程:在二叉排序树中,打印关键码a, b的公共祖先。注:例,若a是b的祖先,则a不算作公共祖先。反之亦然。

二叉排序树&#xff1a; 代码&#xff1a; #include <iostream> using namespace std;// 定义二叉树节点结构 typedef struct BTNode {char show;struct BTNode* left;struct BTNode* right; } BTNode;// 非递归插入节点的函数 BTNode* insertNode(BTNode* root, char k…

【C -> Cpp】由C迈向Cpp (6):静态、友元和内部类

标题&#xff1a;【C -&#xff1e; Cpp】由C迈向Cpp &#xff08;6&#xff09;&#xff1a;静态、友元和内部类 水墨不写bug &#xff08;图片来源于网络&#xff09; 目录 &#xff08;一&#xff09;静态成员 &#xff08;二&#xff09;友元 &#xff08;三&#xff09…

【AI+漫画】程序员小李解决疑难杂症BUG的日常

周末花了点时间制作的AI漫画。 感慨一句&#xff0c;程序人生, 相伴随行。 原文链接&#xff1a;【AI漫画】程序员小李解决疑难杂症BUG的日常

ADS使用记录之使用RFPro进行版图联合仿真

ADS使用记录之使用RFPro进行版图联合仿真 在ADS中&#xff0c;我们往往使用EM仿真来明确电路的实际性能&#xff0c;但是常规的方法我们只会得到S参数&#xff0c;对于场还有电路的电流分布往往不进行检查。但是在实际中&#xff0c;观察场和电流分布是非常有意义的&#xff0…

2024042001-计算机网络 - 物理层

计算机网络 - 物理层 计算机网络 - 物理层 通信方式带通调制 通信方式 根据信息在传输线上的传送方向&#xff0c;分为以下三种通信方式&#xff1a; 单工通信&#xff1a;单向传输半双工通信&#xff1a;双向交替传输全双工通信&#xff1a;双向同时传输 带通调制 模拟信号…

栈和队列(1)

现在是个激动人心的时刻&#xff0c;因为我们来到了栈和队列的章节。 栈是一种特殊的线性表&#xff0c;只允许在一端进行插入和删除操作。进入数据插入和删除的一端叫作栈顶&#xff0c;另一端称为栈底。具有后进先出的特点。 压栈&#xff1a;数据的插入操作叫作进栈/入栈/…

InfiniGate自研网关实现五

17.核心通信组件管理和处理服务映射 引入模块api-gateway-core 到 api-gateway-assist 中进行创建和使用&#xff0c;并拉取自注册中心的映射信息注册到本地的网关通信组件中。 第17节是在第15节的基础上继续完善服务发现的相关功能&#xff0c;把从注册中心拉取的网关映射信…

fastjson1.2.68对于文件操作的分析最全

fastjson1.2.68对于文件操作的分析 前言分析复制文件写入文件读取文件分析poc拓宽场景极限环境poc优化修改再次优化poc的分析 前言 这次分析也是分析了很久&#xff0c;因为每个链子都是自己去跟着分析了的&#xff0c;然后主要是去学习了一下怎么去挖链子 分析 前面漏洞复现…

海外云手机的运作原理和适用场景

海外云手机是一种基于云计算技术的虚拟手机服务&#xff0c;通过将手机操作系统和应用程序托管在远程服务器上&#xff0c;实现用户可以通过互联网连接来使用和管理手机功能&#xff0c;而无需实际拥有物理手机。以下是有关海外云手机的相关信息&#xff1a; 海外云手机的运作原…

ASP.NET在线毕业论文提交系统的设计与实现

摘 要 本设计就很好的解决了上面的问题&#xff0c;它不但能实现毕业生论文的在线提交&#xff1b;还能给教师一定的权限&#xff0c;以在线的方式对自己指导的学生的论文进行审核&#xff1b;并且管理员还可以方便的将每个学生的论文信息按统一的论文排版本格式导出成word文…

Linux平台和Windows平台互传文件

rz和sz的出发对象都是从Linux出发的&#xff0c;例如sz发送&#xff08;Send&#xff09;从Linux->发送到Windows。 rz 从Windows文件发送到Linux中 先创立一个新文本文件 之后将hello Windows输入到该文本文件中 在显示器上显示里面是否有hello Windows内容 sz发送Lin…