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发送Email方法实例
Aug 21 Python
python实现的jpg格式图片修复代码
Apr 21 Python
介绍Python中的__future__模块
Apr 27 Python
python实现同时给多个变量赋值的方法
Apr 30 Python
Python备份目录及目录下的全部内容的实现方法
Jun 12 Python
django在接受post请求时显示403forbidden实例解析
Jan 25 Python
如何用python写一个简单的词法分析器
Dec 18 Python
详解Python3中ceil()函数用法
Feb 19 Python
python实现提取COCO,VOC数据集中特定的类
Mar 10 Python
Python多线程thread及模块使用实例
Apr 28 Python
Pandas的Apply函数具体使用
Jul 21 Python
Python如何获取文件路径/目录
Sep 22 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
php数组函数序列之asort() - 对数组的元素值进行升序排序,保持索引关系
2011/11/02 PHP
使用PHP接受文件并获得其后缀名的方法
2015/08/05 PHP
PHP实现二叉树的深度优先与广度优先遍历方法
2015/09/28 PHP
php+MySql实现登录系统与输出浏览者信息功能
2016/07/01 PHP
PHP通过CURL实现定时任务的图片抓取功能示例
2016/10/03 PHP
PHP Post获取不到非表单数据的问题解决办法
2018/02/27 PHP
js跨域和ajax 跨域问题的实现思路
2009/09/05 Javascript
JS模块与命名空间的介绍
2013/03/22 Javascript
js拖动div 当鼠标移动时整个div也相应的移动
2013/11/21 Javascript
JS 对象属性相关(检查属性、枚举属性等)
2015/04/05 Javascript
jquery插件jquery.LightBox.js实现点击放大图片并左右点击切换效果(附demo源码下载)
2016/02/25 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
2016/05/24 Javascript
Bootstrap编写一个兼容主流浏览器的受众门户式风格页面
2016/07/01 Javascript
jQuery Checkbox 全选 反选的简单实例
2016/11/29 Javascript
详解tween.js 中文使用指南
2018/01/05 Javascript
Python中的ctime()方法使用教程
2015/05/22 Python
深入理解python对json的操作总结
2017/01/05 Python
开源软件包和环境管理系统Anaconda的安装使用
2017/09/04 Python
python数据抓取分析的示例代码(python + mongodb)
2017/12/25 Python
Python 通过requests实现腾讯新闻抓取爬虫的方法
2019/02/22 Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
2020/11/27 Python
HTML5 Canvas渐进填充与透明实现图像的Mask效果
2013/07/11 HTML / CSS
HTML5 video进入全屏和退出全屏的实现方法
2020/07/28 HTML / CSS
美国体育用品在线:Modell’s Sporting Goods
2018/06/07 全球购物
斯巴达比赛商店:Spartan Race
2019/01/08 全球购物
什么是反射?如何实现反射?
2016/07/25 面试题
业务员薪酬管理制度
2014/01/15 职场文书
科技开发中心办公室主任岗位责任制
2014/02/10 职场文书
《海伦?凯勒》教学反思
2014/04/17 职场文书
导游词怎么写
2015/02/04 职场文书
2015年创先争优工作总结
2015/05/23 职场文书
2015年教研工作总结
2015/05/23 职场文书
2015年主婚人婚礼致辞
2015/07/28 职场文书
演讲稿:​快乐,从不抱怨开始!
2019/04/02 职场文书
如何才能写好调研报告?
2019/07/03 职场文书
创业计划书之溜冰场
2019/10/25 职场文书