前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >利用Python实现Union-Find算法

利用Python实现Union-Find算法

原创
作者头像
华科云商小徐
发布于 2025-01-10 03:34:02
发布于 2025-01-10 03:34:02
10600
代码可运行
举报
文章被收录于专栏:小徐学爬虫小徐学爬虫
运行总次数:0
代码可运行

Union-Find(又称 并查集)是一种高效解决 动态连通性问题 的算法。它主要提供两种操作:

  1. Union(x, y):将元素 xy 连接。
  2. Find(x):找到元素 x 所属的集合的标识符(通常是集合的根节点)。

常用的优化策略:

  • 路径压缩(Path Compression):Find 操作中,将访问的节点直接连接到根节点,从而加速后续操作。
  • 按秩合并(Union by Rank):Union 操作中,总是将较小的树合并到较大的树中,以减少树的高度。

1、问题背景

Union-Find 算法又称不交并集算法,是一种用于维护一组元素之间不相交集合的算法。在实际应用中,Union-Find 算法可以用来解决多种问题,例如判断两个元素是否属于同一个集合、将两个集合合并为一个集合等。

在 Union-Find 算法中,每个元素都由一个父节点表示,父节点指向该元素所属的集合的根节点。如果两个元素的父节点相同,则这两个元素属于同一个集合。如果两个元素的父节点不同,则这两个元素不属于同一个集合。

2、解决方案

Python 中 Union-Find 算法有两种实现方法:使用数组和使用字典。

使用数组实现 Union-Find 算法时,每个元素的父节点存储在一个数组中。如果两个元素的父节点相同,则这两个元素属于同一个集合。否则,这两个元素不属于同一个集合。

使用字典实现 Union-Find 算法时,每个元素的父节点存储在一个字典中。字典的键是元素,字典的值是该元素的父节点。如果两个元素的父节点相同,则这两个元素属于同一个集合。否则,这两个元素不属于同一个集合。

下面是使用 Python 实现 Union-Find 算法的示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def union_find_array(lis):
    """
    使用数组实现 Union-Find 算法。
​
    参数:
        lis: 一组元素。
​
    返回:
        一个列表,其中每个元素的父节点存储在一个数组中。
    """
​
    # 创建一个数组,将每个元素的父节点初始化为其自身。
    parents = [i for i in range(len(lis))]
​
    def find(x):
        """
        查找元素 x 的父节点。
​
        参数:
            x: 一个元素。
​
        返回:
            元素 x 的父节点。
        """
​
        # 如果元素 x 的父节点不是其自身,则继续查找元素 x 的父节点。
        if parents[x] != x:
            parents[x] = find(parents[x])
​
        # 返回元素 x 的父节点。
        return parents[x]
​
    def union(x, y):
        """
        将元素 x 和元素 y 所属的集合合并为一个集合。
​
        参数:
            x: 一个元素。
            y: 一个元素。
        """
​
        # 查找元素 x 的父节点。
        x_parent = find(x)
​
        # 查找元素 y 的父节点。
        y_parent = find(y)
​
        # 如果元素 x 和元素 y 所属的集合不是同一个集合,
        # 则将元素 x 和元素 y 所属的集合合并为一个集合。
        if x_parent != y_parent:
            parents[y_parent] = x_parent
​
    # 返回父节点数组。
    return parents
​
​
def union_find_dict(lis):
    """
    使用字典实现 Union-Find 算法。
​
    参数:
        lis: 一组元素。
​
    返回:
        一个字典,其中每个元素的父节点存储在一个字典中。
    """
​
    # 创建一个字典,将每个元素的父节点初始化为其自身。
    parents = {i: i for i in lis}
​
    def find(x):
        """
        查找元素 x 的父节点。
​
        参数:
            x: 一个元素。
​
        返回:
            元素 x 的父节点。
        """
​
        # 如果元素 x 的父节点不是其自身,则继续查找元素 x 的父节点。
        if parents[x] != x:
            parents[x] = find(parents[x])
​
        # 返回元素 x 的父节点。
        return parents[x]
​
    def union(x, y):
        """
        将元素 x 和元素 y 所属的集合合并为一个集合。
​
        参数:
            x: 一个元素。
            y: 一个元素。
        """
​
        # 查找元素 x 的父节点。
        x_parent = find(x)
​
        # 查找元素 y 的父节点。
        y_parent = find(y)
​
        # 如果元素 x 和元素 y 所属的集合不是同一个集合,
        # 则将元素 x 和元素 y 所属的集合合并为一个集合。
        if x_parent != y_parent:
            parents[y_parent] = x_parent
​
    # 返回父节点字典。
    return parents
​
​
# 测试代码。
lis = [[1, 2], [2, 3], [4, 5], [6, 7], [1, 7]]
parents_array = union_find_array(lis)
parents_dict = union_find_dict(lis)
print(parents_array)
print(parents_dict)

上述代码中,union_find_array() 函数和 union_find_dict() 函数分别使用数组和字典实现了 Union-Find 算法。find() 函数和 union() 函数分别是 Union-Find 算法中查找元素父节点和将两个集合合并为一个集合的函数。

使用数组实现 Union-Find 算法的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def union_find_array(lis):
​
    # 创建一个数组,将每个元素的父节点初始化为其自身。
    parents = [i for i in range(len(lis))]
​
    def find(x):
​
        # 如果元素 x 的父节点不是其自身,则继续查找元素 x 的父节点。
        if parents[x] != x:
            parents[x] = find(parents[x])
​
        # 返回元素 x 的父节点。
        return parents[x]
​
    def union(x, y):
​
        # 查找元素 x 的父节点。
        x_parent = find(x)
​
        # 查找元素 y 的父节点。
        y_parent = find(y)
​
        # 如果元素 x 和元素 y 所属的集合不是同一个集合,
        # 则将元素 x 和元素 y 所属的集合合并为一个集合。
        if x_parent != y_parent:
            parents[y_parent] = x_parent
​
    # 返回父节点数组。
    return parents
​
​
# 测试代码。
lis = [[1, 2], [2, 3], [4, 5], [6, 7], [1, 7]]
parents_array = union_find_array(lis)
print(parents_array)

输出结果为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[2, 2, 2, 6, 2]

使用字典实现 Union-Find 算法的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def union_find_dict(lis):
​
    # 创建一个字典,将每个元素的父节点初始化为其自身。
    parents = {i: i for i in lis}
​
    def find(x):
​
        # 如果元素 x 的父节点不是其自身,则继续查找元素 x 的父节点。
        if parents[x] != x:
            parents[x] = find(parents[x])
​
        # 返回元素 x 的父节点。
        return parents[x]
​
    def union(x, y):
​
        # 查找元素 x 的父节点。
        x_parent = find(x)
​
        # 查找元素 y 的父节点。
        y_parent = find(y)
​
        # 如果元素 x 和元素 y 所属的集合不是同一个集合,
        # 则将元素 x 和元素 y 所属的集合合并为一个集合。
        if x_parent != y_parent:
            parents[y_parent] = x_parent
​
    # 返回父节点字典。
    return parents
​
​
# 测试代码。
lis = [[1, 2], [2, 3], [4, 5], [6, 7], [1, 7]]
parents_dict = union_find_dict(lis)
print(parents_dict)

输出结果为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{1: 2, 2: 2, 3: 2, 4: 6, 5: 6, 6: 6, 7: 2}

基本的 Union-Find 非常适合处理动态连通性问题。优化版本结合路径压缩和按秩合并,使其在实际应用中非常高效。可以扩展实现更多功能,如连通性查询、连通分量计数等。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python 运算符与数据类型
运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算,在Python中运算符大致可以分为7种类型:算术运算符、比较运算符、赋值运算符、逻辑运算符、位运算等,下面的例子将依次介绍这几种运算符的使用技巧.
王瑞MVP
2022/12/28
1.9K0
条件语句/变量和基本数据类型
在32位机器上,整数的位数为32位,取值范围为-2**31~2**31-1,即-2147483648~2147483647   在64位系统上,整数的位数为64位,取值范围为-2**63~2**63-1,即-9223372036854775808~9223372036854775807
py3study
2020/01/17
2K0
Python基础之数据类型详解
数字类型与其他编程语言类似,这里不再具体讲解。作为Python中最重要的基础知识,下面主要梳理下字符串、列表、元组、字典、集合的核心知识点。
吾非同
2020/10/13
1K0
python初级:基础知识学习-变量、数据类型、运算符、选择结构
变量是程序中临时存储数据的容器。 变量的赋值:向变量中存储数据 语法:变量名称 = 数据 python代码中,出现了等号~通常情况就是向左边的变量中存储数据 变量作为一个容器,对于数据的操作一般只有四种:增加、删除、修改、查询
全栈程序员站长
2021/09/26
5900
基本数据类型(二)
  列表是 Python 最常用的数据类型,它是有序元素的集合,元素之间以逗号分隔,用中括号括起来,可以是任何数据类型。同时它也是一种序列,支持索引、切片、加、乘和成员检查等。
py3study
2020/01/16
6780
Python--4 基本数据类型
  字符串str是在Python编写程序过程中,最常见的一种基本数据类型。字符串是许多单个子串组成的序列,其主要是用来表示文本。字符串是不可变数据类型,也就是说你要改变原字符串内的元素,只能是新建另一个字符串。
py3study
2020/01/19
9540
Python--4 基本数据类型
python数据类型,格式话输出
 一.程序交互 name = input(“你的名字是:”) #用户输入,输入的任何东西都存储成str(字符串类型)的形式 二.注释的重要性   以后动辄几千行代码的时候,回过头再去看的时候,发现自己都看不懂了,在工作中还会大家一起合作完成代码,不写注释的话,更难以交流了。 单行注释直接在句首写上#就好了 多行注释可用快捷键ctrl+/,或者用三个引号括起来''' 99999999                          12345789                      
py3study
2020/01/19
1.3K0
Python知识点(史上最全)
type()不会认为子类是一种父类类型。 isinstance()会认为子类是一种父类类型
全栈程序员站长
2022/08/27
8360
Python知识点(史上最全)
python数据类型
代码注释分单行和多行注释, 单行注释用#,多行注释可以用三对双引号"""  """
py3study
2020/01/19
5690
【Python】从基础变量类型到各种容器(列表、字典、元组、集合、字符串)
反向索引:从-1开始,-1代表最后一个,-2代表倒数第二个,以此类推,第一个是-len(s)。
杨丝儿
2022/02/17
2.4K0
【Python】从基础变量类型到各种容器(列表、字典、元组、集合、字符串)
02 . Python之数据类型
变量存储在内存中的值。这就意味着在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。 因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符.
iginkgo18
2020/09/27
1.8K0
02 . Python之数据类型
python 基础 数据类型
1、变      量:变量是计算机内存中的一块儿区域,变量可以存储规定范围内的值,而且值可以改变。
py3study
2020/01/07
6670
基本数据类型、输入输出、运算符
数据类型值是变量值的类型,变量值之所以区分类型,是因为变量值是用来记录事物状态的,而事物的状态有不同的种类,对应着,也必须使用不同类型的值去记录它们。
py3study
2020/01/17
5910
python_列表_元组_字典
insert(index, object) 在指定位置index前插入元素object
以某
2023/03/07
2.4K0
python_列表_元组_字典
​Python数据类型
序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
PayneWu
2020/12/18
7480
Python基础(三) | Python的组合数据类型
d.get(key,default) 从字典d中获取键key对应的值,如果没有这个键,则返回default
timerring
2022/09/27
2.7K0
Python基础(三) | Python的组合数据类型
python3_03.数据类型
  Python中的字符串用单引号(')或双引号(")括起来,同时使用反斜杠(\)转义特殊字符。
py3study
2020/01/03
5960
python基础--数据类型
在Python3中有六个标准的数据类型:Number(数字)、String(字符串)、List(列表)、Tuple(元组)、Set(集合)、Dictionary(字典),
ypoint
2019/08/15
1.6K1
Python入门(三):数据结构
切换list[begin:end],获取切换list内元素,从begin开始,至end结束,不包含end
披头
2019/12/26
1.1K0
第一章 python入门
                                        2.获取用户名跟密码,如果用户名是:root  密码是:root 提示正确登录,否则登录失败
py3study
2020/01/17
6270
相关推荐
Python 运算符与数据类型
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验