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 相关文章推荐
django实现分页的方法
May 26 Python
Python判断两个对象相等的原理
Dec 12 Python
Python实现读取字符串按列分配后按行输出示例
Apr 17 Python
pandas apply 函数 实现多进程的示例讲解
Apr 20 Python
pyqt5 禁止窗口最大化和禁止窗口拉伸的方法
Jun 18 Python
python 使用装饰器并记录log的示例代码
Jul 12 Python
详解Django定时任务模块设计与实践
Jul 24 Python
Django 重写用户模型的实现
Jul 29 Python
基于python3实现倒叙字符串
Feb 18 Python
Python greenlet和gevent使用代码示例解析
Apr 01 Python
在Python3.74+PyCharm2020.1 x64中安装使用Kivy的详细教程
Aug 07 Python
python3中TQDM库安装及使用详解
Nov 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/03/02 无线电
PHP 模拟$_PUT实现代码
2010/03/15 PHP
JS中引用百度地图并将百度地图的logo和信息去掉
2013/09/29 Javascript
JavaScript中this的使用详解
2013/11/08 Javascript
angularjs中的单元测试实例
2014/12/06 Javascript
Web表单提交之disabled问题js解决方法
2015/01/13 Javascript
Nodejs学习笔记之测试驱动
2015/04/16 NodeJs
原生js和jquery实现图片轮播淡入淡出效果
2015/04/23 Javascript
javascript实现在指定元素中垂直水平居中
2015/09/13 Javascript
js实现继承的5种方式
2015/12/01 Javascript
javascript创建对象的几种模式介绍
2016/05/06 Javascript
NodeJS远程代码执行
2016/08/28 NodeJs
js实现一键复制功能
2017/03/16 Javascript
浅谈jQuery框架Ajax常用选项
2017/07/08 jQuery
javascript中函数的写法实例代码详解
2018/10/28 Javascript
Angular ui-roter 和AngularJS 通过 ocLazyLoad 实现动态(懒)加载模块和依赖
2018/11/25 Javascript
200行HTML+JavaScript实现年会抽奖程序
2019/01/22 Javascript
Vue开发Html5微信公众号的步骤
2019/04/11 Javascript
React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析
2020/01/06 Javascript
深度解读vue-resize的具体用法
2020/07/08 Javascript
讲解Python中fileno()方法的使用
2015/05/24 Python
Python实现注册登录系统
2017/08/08 Python
Numpy中stack(),hstack(),vstack()函数用法介绍及实例
2018/01/09 Python
对Python中DataFrame选择某列值为XX的行实例详解
2019/01/29 Python
Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】
2019/12/19 Python
python生成大写32位uuid代码
2020/03/03 Python
Python如何在main中调用函数内的函数方式
2020/06/01 Python
俄罗斯和世界各地的酒店预订:Hotels.com俄罗斯
2016/08/19 全球购物
EJB发布WEB服务一般步骤
2012/10/31 面试题
文员个人求职自荐信
2013/09/21 职场文书
教师求职推荐信范文
2013/11/20 职场文书
小学生期末评语
2014/04/21 职场文书
小学红领巾广播稿(3篇)
2014/09/13 职场文书
庆祝教师节活动总结
2015/03/23 职场文书
2015年幼儿园后勤工作总结
2015/04/25 职场文书
2016年教师师德师风承诺书
2016/03/25 职场文书