python实现一个简单的并查集的示例代码
作者:黄天浩 发布时间:2023-05-15 17:14:54
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。常常在使用中以森林来表示。
并查集有三种基本操作,获得根节点,判断两节点是否连通,以及将两不连通的节点相连(相当于将两节点各自的集合合并)
用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实现一个简单的并查集的方式。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
来源:https://segmentfault.com/a/1190000013805875


猜你喜欢
- 序对于如何将py文件打包生成exe可执行文件最简单的应该我觉得就是使用pyinstaller第三方模块下面我就分为三个步骤给大家讲解如何使用
- 使用vue去请求接口发现问题来了:我请求只能请求一次,然后在按按钮去请求的时候发现502(这个是接口定义的)502就是传了空的值过来 这个是
- PyQt5 Qt Designer (Qt设计师)PyQt5是对Qt所有类进行封装, Qt能开发的东西, PyQt都能开发.Qt是强大的GU
- 1、模拟退火算法退火是金属从熔融状态缓慢冷却、最终达到能量最低的平衡态的过程。模拟退火算法基于优化问题求解过程与金属退火过程的相似性,以优化
- Urllib1. Urllib.request.urlopen().read().decode()返回一个二进制的对象,对这个对象进行rea
- 问题背景周一上班,首先向同事了解了一下上周的测试情况,被告知在多实例场景下 MySQL Server hang 住,无法测试下去,原生版本不
- 使用场景:按文件名字正序,批量执行某文件夹下的所有sql文件,并输出日志适合人群:实施工程师一、使用篇1、准备bat文件:1.1、ExecS
- 网上http接口自动化测试Python实现有很多,我也是在慕课网上学习了相关课程,并实际操作了一遍,于是进行一些总结,便于以后回顾温习,有许
- 持久化文件读写:f=open('info.txt','a+')f.seek(0)str1=f.read()i
- 本文实例讲述了Python实现可获取网易页面所有文本信息的网易网络爬虫功能。分享给大家供大家参考,具体如下:#coding=utf-8#--
- 1. raw,mhd 格式医学图像数据转换raw+mhd格式是常见的一种医学图像格式,每一个病人的数据包含一个mhd文件和一个同名的raw文
- MySQL查询不使用索引汇总众所周知,增加索引是提高查询速度的有效途径,但是很多时候,即使增加了索引,查询仍然不使用索引,这种情况严重影响性
- 项目开发中文件的读写是必不可少的下面来简单介绍一下文件的读读文件,首先我们要有文件那我首先自己创建了一个文本文件password.txt内容
- 1.setting--version control--subversion,按照图中红色字体填入对应信息2.配置中途遇到没找到svn.ex
- 一提起Google的产品,大多数人可能都会想到用一个词来形容,“简洁”。简单得来又实用,这就是Google的产品设计方针了。Jon Wile
- 本文实例讲述了Python格式化日期时间的方法。分享给大家供大家参考,具体如下:常用的时间函数如下获取当前日期:time.time()获取元
- Python错误SyntaxError: unexpected EOF while parsing含义是解释器到底了都没找到它要找到的东西出
- 本方法只做学习研究之用,不得用于商业用途若经济条件允许,请支持并购买正版,链接地址:https://www.jetbrains.com/py
- python map函数map()函数map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依
- 最近在研究C++连接数据库的问题。安装了MySQL后,在其安装目录下的include文件夹并没有找到libmysql.lib.这个经过研究,