数据结构(C语言描述)并查集

1 并查集的定义及其简单实现

1.1 定义

在一些应用问题中,需将n个不同的元素划分成一组不相交的集合。开始时,每个元素组成一个单元集合,然后按一定顺序将属于同一组元素的集合合并。其间要反复用到查询某个元素属于哪个集合的运算。适合于描述这类问题的抽象数据类型称为并查集。

1.2 并查集支持的运算

UFunion(A,B,U):将并查集U中的集合A和B合并,其结果取名为A或B。
UFfind(e):找出包含元素e的集合,并返回该集合的名字。

1.3 并查集的应用

确定集合上的等价关系。

1.4 使用注意点

在并查集中需要两种类型的参数:集合名字的类型和元素的类型。

1.5 用数组实现并查集

用数组实现的并查集可描述如下。
在这里插入图片描述
其中,整数n是集合中元素的个数,components是表示元素及其所属子集关系的数组,components[x]表示元素x当前所属的集合的名字。

1.6 函数UFinit(size)

函数UFinit(size)将components初始化成大小为size的单元集合。
在这里插入图片描述

1.7 函数UFfind(e)

UFfind(e)的值就是comonents[e]。
在这里插入图片描述

1.8 函数UFunion(i,j,U)

在这里插入图片描述

2 用父节点数组实现并查集

2.1 父结点数组实现树结构

采用树结构实现并查集的基本思想是:每个集合用一棵树来表示,树的结点用于存储集合中的元素名和一个指向其父结点的指针,树根结点处的元素代表该树所表示的集合,利用映射可以找到集合中元素所对应的树结点。
父结点数组是实现上述树结构的有效方法。
在这里插入图片描述
其中,parent是表示树结构的父结点数组。元素x的父结点为parent[x]。

2.2 函数UFinit(size)

函数UFinit(size)将每个元素初始化为一棵单结点树。
在这里插入图片描述
在这里插入图片描述

2.3 函数UFfind(e,U)

UFfind(e,U)运算就是从元素e相应的结点走到树根处,找出所在集合的名字。
在这里插入图片描述

2.4 函数UFunion(i,j,U)

UFunion(i,j,U)合并两个集合。只要将表示一个集合的树的树根改为表示另一个集合的树的树根的儿子
在这里插入图片描述

2.5 改进并查集结构

改进的并查集结构中增加一个根结点数组root,用来记录树的根结点。当元素e所在结点不是根结点时,root[e]=0,parent[e]表示其父结点;当元素e所在结点是根结点时,root[e]=1,parent[e]的值是树中结点个数。
在这里插入图片描述

2.6 改进函数UFinit(size)

函数UFinit(size)将每个元素初始化为一棵单结点树。
在这里插入图片描述
在这里插入图片描述

2.7 改进函数UFfind(e,U)

UFfind(e,U)运算从运算e相应的结点走到树根处,找出所在集合的名字。
在这里插入图片描述

2.8 改进后函数UFunion(i,j,U)

UFunion(i,j,U)运算将小树合并到大树上。
在这里插入图片描述

2.9 改进函数UFfree(U)

用父结点数组实现并查集UFset时,根结点数组root和父结点数组parent都是动态分配的,需要适时释放所分配的空间。
在这里插入图片描述

2.10 改进函数UFfind(e,U)

加速并查集运算的另一个办法是采用路径压缩技术。在执行UFind运算时, 实际上找到了从一个结点到树根的一条路径。路径压缩是把这条路上的所有结点都改为树根的儿子。实现路径压缩的最简单方法是在这条路上走两次,第一次找到树根,第二次将路上所有结点的父结点都改为树根。
在这里插入图片描述
路径压缩并不影响UFunion运算的时间,它仍然只要O(1)时间,但是路径压缩大大地加速了UFfind运算。

3 小结

这里讲解以不相交的集合为基础的抽象数据类型并查集及其实现方法
并查集支持的主要集合运算是集合查询集合合并运算
数组容易实现并查集,但其集合合并运算效率较低。
树结构实现并查集使得集合合并运算只需要O(1)时间。在最坏情况下,合并运算可能使n个结点的树退化成一条链。
在这种情况下, 对所有元素各执行一次UFfind运算将耗时o(n) 。
为了克服这个缺点, 在合并时采用将小树合并到大树的策略可使每次执行UFfind运算不超过O(logn)时间。
进一步采用路径压缩技术可以使执行UFind需要的平均时间降至0(a(n) ) 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值