并查集的python实现

这一阵子在做leecode题的时候出现了太多的并查集,所以趁此机会想系统性的总结一下相关的知识,以便帮助大家更好的理解。如果有错误希望大家指正

并查集的介绍

并查集是在多集合问题中,刚开始时将每个元素构成一个单元素的集合,然后按照一定的顺序将属于同一组的元素进行合并。在此期间要反复查找一个元素在哪个集合中。

总之,并查集是处理一些不相关集合的合并查询问题的一种树形的数据结构(与它的名字很相符是不是,哈哈)

并查集的理解

为了帮助大家更好的理解,我采用一个比喻来介绍
以武侠小说中的帮派为例,在刚开始时每个人都建立一个帮派,那么他们自己就是帮派的代表人物。(如下图所示)
在这里插入图片描述
之后帮派之间会进行争斗,一些强的帮派会吞并一些弱的帮派,那么弱的帮派也就附属于强的帮派(1和3进行争斗,假设胜者为1)
在这里插入图片描述
假设之后2再和3较量时,3表示拒绝,并说我不和你较量,你要和帮派老大较量,如果2输给1,同时456之间也进行较量,假设较量之后结果如下:
在这里插入图片描述
4和1进行较量时,如果4输给1,那么就会演变成下图:
在这里插入图片描述
以上,就是并查集功能的体现。

并查集的相关功能的python实现

由定义可知,并查集的功能主要是查询和合并。所以,一般会有三个步骤。

初始化

初始化是将每个元素看作一个集合,并将元素本身作为集合中的代表元素。
就相当于上面例子中的每个人建立自己帮派的过程,此时,每个帮派的代表元素都是他自己

n = 64
parents = [0]*64
for i in range(n):
    parents[i] = i

假设有64个元素,我们使用一个等长的列表来存储每个元素所属列表的代表元素

查询

查询过程就是查询元素所在集合的代表元素的过程。
相当于上面例子中的帮派之间争斗时,需要找到小弟的大哥来进行比较

def find(x):
    if parents[x] == x:
        return x
    else:
        return find(parents[x])

在这个函数中使用了递归的思想去找到根节点,也就是例子最后的1

合并

合并的过程就是将属于相同集合的元素进行合并的过程。相当于例子中的帮派的吞并过程
先找到两个集合的代表元素,将前者的父节点设为后者即可

def unite(x,y):
    parents[find(x)] = find(y)

结语

这是我看大神的介绍理解的一般的并查集的思路。其实,这种最基本的并查集的思路还可以进一步的优化,如进行路径压缩和按照树的深度来选择合并的方式,以便降低时间复杂度

如果有错误希望大家指正,我会立即修改。
希望对你有所帮助
(附上大神所发布的链接https://zhuanlan.zhihu.com/p/93647900)

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值