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循环语句
Nov 20 Python
Python向MySQL批量插数据的实例讲解
Mar 31 Python
Python 爬虫之Beautiful Soup模块使用指南
Jul 05 Python
Python使用Flask-SQLAlchemy连接数据库操作示例
Aug 31 Python
更改Python的pip install 默认安装依赖路径方法详解
Oct 27 Python
pyqt5 实现多窗口跳转的方法
Jun 19 Python
pyinstaller打包单个exe后无法执行错误的解决方法
Jun 21 Python
Pytorch中的variable, tensor与numpy相互转化的方法
Oct 10 Python
Python dict和defaultdict使用实例解析
Mar 12 Python
Django Serializer HiddenField隐藏字段实例
Mar 31 Python
python matlab库简单用法讲解
Dec 31 Python
Python生成九宫格图片的示例代码
Apr 14 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
一个用php3编写的简单计数器
2006/10/09 PHP
PHP请求远程地址设置超时时间的解决方法
2016/10/29 PHP
thinkphp实现把数据库中的列的值存到下拉框中的方法
2017/01/20 PHP
PHP中的访问修饰符简单比较
2019/02/02 PHP
文档对象模型DOM通俗讲解
2013/11/01 Javascript
jquery选择器之基本过滤选择器详解
2014/01/27 Javascript
JS中判断JSON数据是否存在某字段的方法
2014/03/07 Javascript
node.js中watch机制详解
2014/11/17 Javascript
在JavaScript中操作时间之getMonth()方法的使用
2015/06/10 Javascript
javascript实现随机读取数组的方法
2015/08/03 Javascript
jQuery实现的网页左侧在线客服效果代码
2015/10/23 Javascript
js编写贪吃蛇的小游戏
2020/08/24 Javascript
js简单倒计时实现代码
2016/04/30 Javascript
angular.js+node.js实现下载图片处理详解
2017/03/31 Javascript
Vue-Access-Control 前端用户权限控制解决方案
2017/12/01 Javascript
js构造函数constructor和原型prototype原理与用法实例分析
2020/03/02 Javascript
详解在Vue.js编写更好的v-for循环的6种技巧
2020/04/14 Javascript
Express 配置HTML页面访问的实现
2020/11/01 Javascript
[02:56]DOTA2矮人直升机 英雄基础教程
2013/11/26 DOTA
[00:43]FTP典藏礼包 DOTA2三大英雄霸气新套装
2014/03/21 DOTA
[02:43]DOTA2英雄基础教程 半人马战行者
2014/01/13 DOTA
[01:00:26]Ti4主赛事胜者组第一天 EG vs NEWBEE 1
2014/07/19 DOTA
用Python编写一个国际象棋AI程序
2014/11/28 Python
Python脚本处理空格的方法
2016/08/08 Python
对Python 两大环境管理神器 pyenv 和 virtualenv详解
2018/12/31 Python
Python2和Python3中@abstractmethod使用方法
2020/02/04 Python
CSS3对图片照片进行边缘模糊处理的实现
2018/08/08 HTML / CSS
CSS3 重置iphone浏览器按钮input,select等表单元素的默认样式
2014/10/11 HTML / CSS
5 个强大的HTML5 API 函数推荐
2014/11/19 HTML / CSS
美国第二大连锁药店:Rite Aid
2019/04/03 全球购物
学期自我鉴定范文
2013/10/01 职场文书
土建工程师岗位职责
2014/06/10 职场文书
践行党的群众路线心得体会
2014/11/05 职场文书
结婚堵门保证书
2015/05/08 职场文书
心灵点滴观后感
2015/06/02 职场文书
Javascript中的解构赋值语法详解
2021/04/02 Javascript