使用Python实现不相交集(Union-Find算法)入门

2025年2月22日 | 阅读 5 分钟

数据结构中最基本的数据结构之一,不相交集(Disjoint Set),也称为并查集(Union-Find)方法,能够有效地处理将组件拆分成不相交集的问题。这种方法在处理涉及连通性和等价关系的问题时非常有用。其一个常见的应用是实现 Kruskal 算法来确定图的最小生成树。

本文将深入探讨不相交集(Disjoint Set),涵盖其应用、用法和 Python 实现。

不相交集基础

能够将组件分组到不重叠的组中的数据结构称为不相交集数据结构。它维护一组不相交集,每个集合都有一个代表元素(也称为根元素)。集合可以通过其根元素进行识别和区分。

不相交集数据结构支持多种重要操作,包括创建新集合、合并现有集合以及确定集合的根元素。由于这些操作即使在大型集合上也能快速完成,因此不相交集数据结构适用于各种用途。

不相交集的功能是管理组件到不相交集的划分。每个集合都有一个代表元素的概念至关重要,因为它有助于确定元素之间的等价关系和连通性。不相交集主要支持以下操作:Union(合并)、Find(查找)和 MakeSet(创建集合)。

以下是不相交集的主要概念:

  • MakeSet(x):创建一个包含元素 x 的新集合。
  • Union(x, y):通过合并包含元素 x 和 y 的集合来创建一个单一集合。
  • Find(x):返回包含 x 的集合的代表元素。

要创建一个新集合,只需初始化一个新元素并将其指定为其自身的代表元素。要合并两个集合,找出每个集合的根元素,然后将一个集合的根元素指定为另一个集合的父节点。可以通过沿着父指针链直到找到一个指向自身的元素来定位集合的根元素。

如何创建不相交集?

如果集合没有共同的元素,即交集为空,则称它们为不相交集。不相交集的目的在于有效地管理元素到不相交集的划分,每个集合都有一个代表元素。主要目标是高效地执行合并两个集合或确定两个组件是否属于同一集合等任务。

不相交集数据结构执行以下功能:

  • 向不相交集添加新集合
  • Union 操作将不同的集合合并成一个不相交集。
  • 使用 Find 操作确定不相交集的代表元素。
  • 验证两个集合是否不相交。

不相交集的组成部分

  1. 父数组 (Parent Array):不相交集中的每个元素都有一个父元素,父数组维护着这种关系,它是不相交集的核心组成部分。每个元素最初都将其自身初始化为父节点,从而形成单个元素的集合。
  2. 秩数组 (Rank Array):为了优化 Union 操作,秩数组至关重要。秩数组用于存储每个节点的秩并监测每棵树的深度,以维护平衡的结构并防止树结构过度增长。

此 Python 代码片段可用于定义父数组和秩数组。

创建了一个名为 Disjoint() 的类,在该类中定义了父数组和秩数组。

不相交集操作

1. MakeSet(x)

使用不相交集的第一步是执行 MakeSet 操作。它创建一个只包含一个元素 x 的集合。这包括将秩初始化为 0,并将 x 的父节点设置为它自身。

2. Find(x)

Find 操作是 Disjoint Set 的关键组成部分,它查找包含元素 x 的集合的根(代表元素)。为了优化将来的 Find 操作,使用了路径压缩(扁平化树结构)。

3. Union(x)

Union 操作将包含元素 x 和 y 的集合合并。为了创建平衡有效的结构,它使用秩将深度较小的树合并到深度较大的树上。

综合了所有结构和操作,这就是不相交集的工作原理。

Python 中的不相交集示例

以下代码提供了一个解释不相交集工作原理的示例。

输出

1

在用大小为 6 初始化集合后,使用一个单独的 make_set 函数为从 0 到 5 的每个元素构建集合。然后对包含元素 0、2、1、3 和 4 的集合执行 Union 操作。为了找到包含元素 1 的集合的代表元素,最后调用 find 方法。接下来,为前五个元素创建集合。在第一个 Union 操作中合并了包含元素 0 和 2 的集合。在第二个 Union 操作中合并了包含元素 1 和 3 的集合。在第三个 Union 操作中合并了包含元素 1 和 0 的集合。在第四个 Union 操作中合并了包含元素 3 和 4 的集合。元素 0 到 3 属于同一集合。

不相交集的应用

不相交集已在各个领域和子领域中使用。一些最广泛使用的应用如下:

  • Kruskal 算法:此确定图的最小生成树的技术经常使用不相交集。
  • 连通分量:在图论中,使用不相交集来查找无向图的连通分量。
  • 动态连通性:它用于处理元素被添加或移除且需要有效更新连通性信息的情况。

结论

并查集规则允许实现不相交集信息结构,这是一个对图算法和动态连通性问题有益的工具。由于路径压缩和按秩合并非常高效,并且可以在几乎恒定的时间内执行基本操作,因此理解和实现此算法对于解决计算机科学的各种难题至关重要。