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中的pprint折腾记
Jan 21 Python
Python可跨平台实现获取按键的方法
Mar 05 Python
Python httplib模块使用实例
Apr 11 Python
pymongo为mongodb数据库添加索引的方法
May 11 Python
Fiddler如何抓取手机APP数据包
Jan 22 Python
python实现多线程抓取知乎用户
Dec 12 Python
python实现数据图表
Jul 29 Python
numpy中实现ndarray数组返回符合特定条件的索引方法
Apr 17 Python
python实现H2O中的随机森林算法介绍及其项目实战
Aug 29 Python
python实现按关键字筛选日志文件
Dec 24 Python
python实现logistic分类算法代码
Feb 28 Python
python中filter,map,reduce的作用
Jun 10 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
PHP5.3的垃圾回收机制(动态存储分配方案)深入理解
2012/12/10 PHP
PHP向浏览器输出内容的4个函数总结
2014/11/17 PHP
php统计数组元素个数的方法
2015/07/02 PHP
PHP对象克隆clone用法示例
2016/09/28 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
2020/04/04 PHP
JavaScript高级程序设计 阅读笔记(四) ECMAScript中的类型转换
2012/02/27 Javascript
用js实现trim()的解决办法
2013/04/16 Javascript
js 实现 input type="file" 文件上传示例代码
2013/08/07 Javascript
浅析JavaScript原型继承的陷阱
2013/12/03 Javascript
JS关闭窗口与JS关闭页面的几种方法小结
2013/12/17 Javascript
JavaScript获取伪元素(Pseudo-Element)属性的方法技巧
2015/03/13 Javascript
javascript中Math.random()使用详解
2015/04/15 Javascript
JavaScript实现cookie的写入、读取、删除功能
2015/11/05 Javascript
详解AngularJS中ng-src指令的使用
2016/09/07 Javascript
BootStrap的两种模态框方式
2017/05/10 Javascript
在vue-cli脚手架中配置一个vue-router前端路由
2017/07/03 Javascript
Vue2.0 多 Tab切换组件的封装实例
2017/07/28 Javascript
JavaScript中关于base64的一些事
2019/05/06 Javascript
vue实现单一筛选、删除筛选条件
2020/10/26 Javascript
Python实现115网盘自动下载的方法
2014/09/30 Python
python+influxdb+shell编写区域网络状况表
2018/07/27 Python
Python数据可视化库seaborn的使用总结
2019/01/15 Python
python框架flask入门之环境搭建及开启调试
2020/06/07 Python
PyCharm上安装Package的实现(以pandas为例)
2020/09/18 Python
Canvas globalCompositeOperation
2018/12/18 HTML / CSS
英国外籍人士的在线超市:British Corner Shop
2019/06/03 全球购物
学前教育毕业生自荐信
2013/10/29 职场文书
优秀应届毕业生自荐信
2013/11/16 职场文书
企事业单位求职者的自我评价
2013/12/28 职场文书
产品设计开发计划书
2014/05/07 职场文书
房产证明范本
2015/06/19 职场文书
小组组名及励志口号
2015/12/24 职场文书
2016年九九重阳节活动总结
2016/04/01 职场文书
PyTorch 实现L2正则化以及Dropout的操作
2021/05/27 Python
MYSQL 无法识别中文的永久解决方法
2021/06/03 MySQL