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获取beautifulphoto随机某图片代码实例
Dec 18 Python
解决python写的windows服务不能启动的问题
Apr 15 Python
对TensorFlow的assign赋值用法详解
Jul 30 Python
Python WEB应用部署的实现方法
Jan 02 Python
python中比较两个列表的实例方法
Jul 04 Python
Python 实用技巧之利用Shell通配符做字符串匹配
Aug 23 Python
Python + Requests + Unittest接口自动化测试实例分析
Dec 12 Python
python中return的返回和执行实例
Dec 24 Python
python实现单张图像拼接与批量图片拼接
Mar 23 Python
Python日志处理模块logging用法解析
May 19 Python
Python使用Chrome插件实现爬虫过程图解
Jun 09 Python
基于PyTorch的permute和reshape/view的区别介绍
Jun 18 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
2021年最新CPU天梯图
2021/03/04 数码科技
php Mysql日期和时间函数集合
2007/11/16 PHP
PHP实现简单爬虫的方法
2015/07/29 PHP
PDO::beginTransaction讲解
2019/01/27 PHP
JavaScript 编程引入命名空间的方法与代码
2007/08/13 Javascript
Javascript YUI 读码日记之 YAHOO.util.Dom - Part.3
2008/03/22 Javascript
JQuery为textarea添加maxlength属性并且兼容IE
2013/04/25 Javascript
js中parseInt函数浅谈
2013/07/31 Javascript
jQuery回车实现登录简单实现
2013/08/20 Javascript
JavaScript数据结构和算法之二叉树详解
2015/02/11 Javascript
JavaScript保存并运算页面中数字类型变量的写法
2015/07/06 Javascript
js实现统计字符串中特定字符出现个数的方法
2016/08/02 Javascript
AngularJS基础 ng-open 指令简单实例
2016/08/02 Javascript
AngularJs验证重复密码的方法(两种)
2016/11/25 Javascript
微信小程序 登陆流程详细介绍
2017/01/17 Javascript
ES6新特性之字符串的扩展实例分析
2017/04/01 Javascript
手机注册发送验证码倒计时的简单实例
2017/11/15 Javascript
原生js实现无缝轮播图效果
2021/01/28 Javascript
[01:34]传奇从这开始 2016国际邀请赛中国区预选赛震撼开启
2016/06/26 DOTA
python实现中文分词FMM算法实例
2015/07/10 Python
Python数据结构与算法之图结构(Graph)实例分析
2017/09/05 Python
python先序遍历二叉树问题
2017/11/10 Python
Python+Django搭建自己的blog网站
2018/03/13 Python
Python实现两个list求交集,并集,差集的方法示例
2018/08/02 Python
python-pyinstaller、打包后获取路径的实例
2019/06/10 Python
Python 等分切分数据及规则命名的实例代码
2019/08/16 Python
keras模型可视化,层可视化及kernel可视化实例
2020/01/24 Python
css3编写浏览器背景渐变背景色的方法
2018/03/05 HTML / CSS
一篇.NET面试题
2014/09/29 面试题
助人为乐表扬信范文
2014/01/14 职场文书
《春雨》教学反思
2014/04/24 职场文书
中等生评语大全
2014/05/04 职场文书
2014年打非治违工作总结
2014/11/13 职场文书
建筑安全员岗位职责
2015/02/15 职场文书
Python还能这么玩之用Python做个小游戏的外挂
2021/06/04 Python
MySQL中B树索引和B+树索引的区别详解
2022/03/03 MySQL