使用 Python 介绍不相交集(并查集算法)

2024 年 8 月 29 日 | 4 分钟阅读

引言

在计算机科学中,Disjoint Set,通常称为 Union-Find 数据结构,是一种用于维护对象集合并回答有关其连通性查询的有效工具。在 Python 中,通常用于创建 Disjoint Set 的 Union-Find 算法在解决包含不重复或不重叠集合的问题方面非常有效。它在图论、计算机网络和图像处理等多种领域都有应用。

关键操作

Disjoint Set 数据结构支持两个主要操作:

Union(合并或连接): 将两个集合合并成一个集合。

Find(查找或查找代表元): 确定一个集合的代表(首领)元素,以使用 Find 方法判断两个元素是否属于同一个集合。

代码

输出

0
4

示例

我们希望根据特定标准将一组六个元素 {0, 1, 2, 3, 4, 5} 分成若干组。我们将使用 Disjoint Set 数据结构对这些元素执行 Union 和 Find 操作。

1. 初始化

我们从每个元素都自成一个集合开始,因此,我们的 Disjoint Set 最初的 parent 数组值为 [0, 1, 2, 3, 4, 5],rank 数组值为 [0, 0, 0, 0, 0, 0]。

{0}, {1}, {2}, {3}, {4}, {5}

2. Union 操作

让我们使用 Union 操作将以下项目组合在一起:

Union(0, 1)

  • 元素 0 和 1 被合并。此过程将元素 0 的父节点更改为元素 1,或者反之亦然。由于 1 现在有一个子节点,我们还增加了 1 的秩。
  • 完成此过程后,我们的 Disjoint Set 如下所示:

{0, 1}, {2}, {3}, {4}, {5}

  • rank 数组变为 [0, 1, 0, 0, 0, 0],parent 数组变为 [1, 1, 2, 3, 4, 5]。

Union (2, 3)

  • 元素 2 和 3 被合并。通过此过程,元素 2 的父节点被更改为元素 3,或者反之亦然。鉴于 3 现在有一个子节点,我们还将其秩增加到 1。
  • 完成此过程后,我们的 Disjoint Set 如下所示:

{0, 1}, {2, 3}, {4}, {5}

  • rank 数组变为 [0, 1, 0, 1, 0, 0],parent 数组变为 [1, 1, 3, 3, 4, 5]。

Union(0, 2)

  • 元素 0(位于集合“0, 1”中)和元素 2(位于集合“2, 3”中)被合并。由于其秩高于元素 2,此操作将元素 0 的父节点从 2 更改为 3。
  • 完成此过程后,我们的 Disjoint Set 如下所示:

{0, 1, 2, 3}, {4}, {5}

  • rank 数组变为 [0, 1, 0, 2, 0],parent 数组变为 [3, 3, 3, 3, 4, 5]。(注意:原文此处 rank 数组示例遗漏了一个元素,根据上下文推测应为 [0, 1, 0, 2, 0, 0])

3. Find 操作

  • Find 操作可用于查找集合的代表(首领)元素,并确定两个项目是否属于该集合。
  • Find(0):我们找到 3 作为元素 0 的代表。
  • Find(4):我们识别元素 4 的代表,即数字 4。
  • 这些发现表明,元素 0、1、2 和 3 属于同一个集合,而元素 4 属于另一个集合。

结论

Disjoint Set 是一种用于组织对象集合并有效检测其连通性的灵活数据结构。它在 Python 中使用 Union-Find 算法实现。它在网络算法和图论等许多领域都有应用。Disjoint Set 操作 Union 和 Find 在此数据结构中至关重要。Find 操作定位集合的代表元素,而 Union 函数将两个不同的集合合并成一个。这些操作共同使我们能够根据连通性或其他因素对元素进行分类。

在 Disjoint Set 实现中,parent 数组描述了集合关系,而 rank 数组用于优化 Union 操作期间的树平衡。通过路径压缩进一步提高了 Find 操作的效率。我们逐步展示了 Disjoint Set 的工作原理,从初始化单个集合到执行 Union 和 Find 操作。这种强大的数据结构是一种有用的算法问题解决方法,因为它可以简化诸如集合操作和相关组件等复杂问题。


下一个主题Python MoviePy 入门