python 并查集_并查集的3种基本操作

并查集中包含 3 种基础操作,包括构建新的集合(MAKE-SET)、合并集合(UNION)和查找某个元素所在的集合(FIND-SET)。

设 x、y 分别为并查集中任意集合中的元素,则各操作详情如下:

1) MAKE-SET(x):构建新的集合

在初始化阶段,需要将元素构建成并查集结构。在此过程中,为所有的元素都建立一个独立的集合,每个新集合中仅包含一个元素,即对于 MAKE-SET(x) 过程,构建一个只包含 x 元素的集合。由于并查集中的各个集合不相交,因此,元素 x 不会出现在其他集合中。

2) UNION(x,y):合并两个集合

该过程中,将 x 元素所在的集合 Sx 和 y 元素所在的集合 Sy 合并为一个新的集合。为了保持并查集中各个集合互不相交的特性,需要在完成合并后删除原集合 Sx 和 Sy,同时,从新集合 Sx∪Sy中任意选取一个元素作为新集合的代表元素。

在实际操作中,为了提升执行效率,通常将其中一个集合并入另一个集合中来代替删除操作。

3) FIND-SET(x):查找某元素所在的集合

在该过程中,给定元素 x,需要返回一个指针,该指针指向包含 x 的集合的代表。

在实现过程中,维护两个数组分别保存各元素的所属集合的代表元素和集合的大小,分别用 fatherList 和 sizeList 表示:

MAKE-SET(x) 过程,初始化每个节点的代表元素为自身,每个节点各自组成一个集合;

FIND-SET(x) 过程,用递归的方式获取当前元素 x 所属集合的代表元素,同时在该过程中进行路径压缩;

UNION 过程,不断将两个集合进行合并,选择较大集合的代表元素作为新集合的代表元素,即修改较小集合中各个元素的代表元素信息,可减小改动量,提升操作效率。

并查集的 3 种基本操作代码:

class Union_Find_Set(object):

# 初始化

def __init__(self, input):

# 初始化两个列表

self.fatherList = {} # 保存元素所属集合的代表元素

self.sizeList = {} # 保存父节点包含的元素个数

for x in input:

self.make_set(x)

# MAKE-SET操作

# 将节点的父节点设为自身,size设为1

def make_set(self, x):

self.fatherList[x] = x

self.sizeList[x] = 1

# FIND-SET操作

# 采用递归的策略定位父节点

# 在父节点查找过程中,将当前节点连接到父节点上,进行路径压缩

def find_set(self, x):

father = self.fatherList[x]

if(x != father): # 递归定位父节点

father = self.find_set(father)

self.fatherList[x] = father # 路径压缩

return father

# UNION操作

# 将a和b两个集合合并在一起

def union(self, a, b):

if a is None or b is None:

return

a_father = self.find_set(a) # 获取两元素所在集合的代表元素

b_father = self.find_set(b)

if(a_father != b_father):

a_size = self.sizeList[a_father] # 获取两元素所在集合的大小

b_size = self.sizeList[b_father]

if(a_size >= b_size): # 将规模较小的集合合并到规模较大的集合下面

self.fatherList[b_father] = a_father

self.sizeList[a_father] = a_size + b_size

self.sizeList[b_father] = 0

else:

self.fatherList[a_father] = b_father

self.sizeList[b_father] = a_size + b_size

self.sizeList[a_father] = 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值