python实现一个简单的并查集的示例代码


Posted in Python onMarch 19, 2018

并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。常常在使用中以森林来表示。

并查集有三种基本操作,获得根节点,判断两节点是否连通,以及将两不连通的节点相连(相当于将两节点各自的集合合并)

用UnionFind类来表示一个并查集,在构造函数中,初始化一个数组parent,parent[i]表示的含义为,索引为i的节点,它的直接父节点为parent[i]。初始化时各个节点都不相连,因此初始化parent[i]=i,让自己成为自己的父节点,从而实现各节点不互连。

def __init__(self, n):
    self.parent = list(range(n))

由于parent[i]仅表示自己的直接父节点,查询两个节点是否相交需要比较它们的根节点是否相同。因此要封装一个查询自己根节点的方法。

def get_root(self, i):
    while i != self.parent[i]:
      i = self.parent[i]

    return i

接下来可以通过来比较根节点是否相同来判断两节点是否连通。

def is_connected(self, i, j):
    return self.get_root(i) == self.get_root(j)

当要连通两个节点时,我们要将其中一个节点的根节点的parent,设置为另一个节点的根节点。注意,连通两个节点并非仅仅让两节点自身相连,实际上是让它们所属的集合实现合并。

def union(self, i, j):
    i_root = self.get_root(i)
    j_root = self.get_root(j)
    self.parent[i_root] = j_root

接下来我们做两个小优化。

由于调用get_root时需要通过不断找自己的直接父节点,来寻找根节点,如果这棵树的层级过深,会导致性能受到严重影响。因此我们需要在union时,尽可能的减小合并后的树的高度。

在构造函数中新建一个数组rank,rank[i]表示节点i所在的集合的树的高度。

因此,当合并树时,分别获得节点i和节点j的root i_root和j_root之后,我们通过访问rank[i_root]和rank[j_root]来比较两棵树的高度,将高度较小的那棵连到高度较高的那棵上。如果高度相等,则可以随便,并将rank值加一。

def union(self, i, j):
    i_root = self.get_root(i)
    j_root = self.get_root(j)

    if self.rank[i_root] == self.rank[j_root]:
      self.parent[i_root] = j_root
      self.rank[j_root] += 1
    elif self.rank[i_root] > self.rank[j_root]:
      self.parent[j_root] = i_root
    else:
      self.parent[i_root] = j_root

通过对union操作的改良可以防止树的高度过高。我们还可以对get_root操作本身进行优化。

当前每次执行get_root时,需要一层一层的找到自己的父节点,很费时。由于根节点没有父节点,并且文章开始处提到过如果一个节点没有父节点,那么它的父节点就是自己,因此可以说只有根节点的父节点是自己本身。现在我们加上一个判断,判断当前节点的父节点是否为根节点,如果不为根节点,就递归地将自己的父节点设置为根节点,最后返回自己的父节点。

def get_root(self, i):
    if self.parent[i] != self.parent[self.parent[i]]:
      self.parent[i] = self.get_root(self.parent[i])
    return self.parent[i]

以上是python实现一个简单的并查集的方式。希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python多线程同步Lock、RLock、Semaphore、Event实例
Nov 21 Python
python数据清洗系列之字符串处理详解
Feb 12 Python
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
Jan 05 Python
python使用正则筛选信用卡
Jan 27 Python
Python3.5实现的三级菜单功能示例
Mar 25 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
Jun 04 Python
pyqt5 获取显示器的分辨率的方法
Jun 18 Python
在Django admin中编辑ManyToManyField的实现方法
Aug 09 Python
简单瞅瞅Python vars()内置函数的实现
Sep 27 Python
Pycharm如何导入python文件及解决报错问题
May 10 Python
基于python实现查询ip地址来源
Jun 02 Python
使用pandas生成/读取csv文件的方法实例
Jul 09 Python
python使用筛选法计算小于给定数字的所有素数
Mar 19 #Python
python将每个单词按空格分开并保存到文件中
Mar 19 #Python
python将文本分每两行一组并保存到文件
Mar 19 #Python
python: line=f.readlines()消除line中\n的方法
Mar 19 #Python
Python File readlines() 使用方法
Mar 19 #Python
Python cookbook(数据结构与算法)筛选及提取序列中元素的方法
Mar 19 #Python
django用户注册、登录、注销和用户扩展的示例
Mar 19 #Python
You might like
中英文字符串翻转函数
2008/12/09 PHP
《PHP编程最快明白》第七讲:php图片验证码与缩略图
2010/11/01 PHP
ThinkPHP空模块和空操作详解
2014/06/30 PHP
ThinkPHP在新浪SAE平台的部署实例
2014/10/31 PHP
visual studio code 调试php方法(图文详解)
2017/09/15 PHP
php操作redis命令及代码实例大全
2020/11/19 PHP
JS localStorage实现本地缓存的方法
2013/06/22 Javascript
JS实现的页面自定义滚动条效果
2015/10/26 Javascript
基于JavaScript实现瀑布流效果(循环渐近)
2016/01/27 Javascript
AngularJS教程之环境设置
2016/08/16 Javascript
node.js路径处理方法以及绝对路径详解
2021/03/04 Javascript
jquery编写日期选择器
2017/03/16 Javascript
Vue实战之vue登录验证的实现代码
2017/10/31 Javascript
解决使用Vue.js显示数据的时,页面闪现原始代码的问题
2018/02/11 Javascript
微信开发之企业付款到银行卡接口开发的示例代码
2018/09/18 Javascript
微信小程序非跳转式组件授权登录的方法示例
2019/05/22 Javascript
通过原生vue添加滚动加载更多功能
2019/11/21 Javascript
微信小程序实现滑动翻页效果(完整代码)
2019/12/06 Javascript
vue使用map代替Aarry数组循环遍历的方法
2020/04/30 Javascript
[03:33]TI9战队采访 - Infamous
2019/08/20 DOTA
python将人民币转换大写的脚本代码
2013/02/10 Python
Python三元运算实现方法
2015/01/12 Python
在Django的session中使用User对象的方法
2015/07/23 Python
Python使用回溯法子集树模板解决迷宫问题示例
2017/09/01 Python
Python SMTP发送邮件遇到的一些问题及解决办法
2018/10/24 Python
程序员写Python时的5个坏习惯,你有几条?
2018/11/26 Python
获取Pytorch中间某一层权重或者特征的例子
2019/08/17 Python
python requests包的request()函数中的参数-params和data的区别介绍
2020/05/05 Python
python装饰器代码深入讲解
2021/03/01 Python
Spartoo英国:欧洲最大的网上鞋店
2016/09/13 全球购物
德国最大的网上足球商店:11teamsports
2019/09/11 全球购物
教师党性分析材料
2014/02/04 职场文书
护士进修自我鉴定
2014/02/07 职场文书
大学生简短的自我评价分享
2014/02/20 职场文书
2014年政教处工作总结
2014/12/20 职场文书
干货干货!2019最新优秀创业计划书
2019/03/21 职场文书