使用Python解决汉诺塔难题

2025 年 8 月 28 日 | 阅读 6 分钟

在本教程中,我们将使用 Python 程序来实现著名的汉诺塔谜题。我们将使用递归函数来解决这个问题。

要了解更多关于 Python 中的递归函数,请参考页面 python-factorial-number-using-recursion

汉诺塔

汉诺塔是由法国数学家埃德华·卢卡斯 (Edouard Lucas) 于 1883 年引入的一个数学谜题。它包含三个塔(柱子)和两个或更多的盘子(如下图所示)。

Tower of Hanoi Puzzle Using Python

盘子可以有不同的尺寸,并且按照递减的顺序排列,这意味着最大的盘子放在底部,较小的盘子放在中间,三个盘子中最小的放在顶部。在本例中,我们使用了三个盘子,但盘子的数量可以增加或减少;但是,塔的数量必须是 3。

游戏规则

这个谜题的目标是在不破坏排列顺序的情况下,将所有盘子移动到另一个塔上,即最大的盘子堆叠在底部,最小的盘子堆叠在顶部。

以下是汉诺塔谜题的规则:

  • 一次只能移动一个圆盘。
  • 您只能取走最上面的盘子。
  • 不允许将大盘子放在小盘子上面。

下面是使用三个盘子解决汉诺塔谜题的分步说明。

步骤 0:所有盘子都按升序放在柱子上。

Tower of Hanoi Puzzle Using Python

步骤 1:我们将最上面的盘子移到中间的塔。

Tower of Hanoi Puzzle Using Python

步骤 2:接下来,我们将中间的盘子移到第三个塔。结果,每个塔上都会有一个盘子。

Tower of Hanoi Puzzle Using Python

步骤 3:将盘子从第二个塔移到第三个塔。

Tower of Hanoi Puzzle Using Python

步骤 4:将第一个盘子从塔一移到塔二。

Tower of Hanoi Puzzle Using Python

步骤 5:再次将最上面的盘子从塔 3 移到塔 1。

Tower of Hanoi Puzzle Using Python

步骤 6:接下来将盘子从塔 3 移到塔 2 的顶部。

Tower of Hanoi Puzzle Using Python

步骤 7:最后一步是将盘子从塔 1 移到塔 2 的顶部。

Tower of Hanoi Puzzle Using Python

结果,我们成功地将所有盘子从一个塔移到了另一个塔,并遵守了所有规则。

Tower of Hanoi Puzzle Using Python

在汉诺塔谜题中,移动的次数可以使用2ⁿ - 1步来计算(其中 n 代表盘子数量)。

在我们的例子中,因为我们有 3 个盘子,所以上述公式的计算结果是2³ - 1 = 7步。

解决汉诺塔的算法

汉诺塔的算法非常简单,如果您一开始就理解了如何移动 1 个盘子、2 个盘子,最后移动 3 个盘子的逻辑。我们将三个塔命名为源 (source)目标 (target)辅助 (aux)(这些名称是临时给出的,以便于跟踪盘子在不同塔之间的移动)。

对于 1 个盘子

它可以很容易地在塔之间移动。它可以从源盘移动到目标盘。

对于 2 个盘子

  • 由于我们只能移动最上面的盘子,我们将它移到辅助盘。
  • 接下来,我们将下面的盘子移到目标盘。
  • 最后一步是将较小的盘子从辅助盘移到目标盘。

对于 3 个盘子

由于我们已经理解了移动一个盘子和两个盘子的逻辑,我们可以轻松得出三个盘子汉诺塔的算法。我们将分两部分来得出结论。最下面的盘子(第 n 个或最大的盘子)是第一部分,所有其他盘子(n-1 个)将在第二部分解决。

目标是将盘子n(最大的盘子)从源盘移动到目标盘,并将所有其他 (n-1) 个盘子堆叠在上面。我们可以想象以递归方式对所有给定的盘子集应用相同的逻辑。

步骤如下:

  • 创建一个tower_of_hanoi递归函数,并传递两个参数:盘子数量 n 和盘子的名称,例如源 (source)、辅助 (aux)目标 (target)
  • 我们可以定义基本情况,当盘子数量为 1 时。在这种情况下,只需将这一个盘子从移动到目标并返回。
  • 现在,使用目标盘作为辅助盘,将剩余的 n-1 个盘子从盘移动到辅助盘。
  • 然后,将源盘上剩余的 1 个盘子移到目标盘。
  • 使用源盘作为辅助盘,将辅助盘上的 n-1 个盘子移动到目标盘。

Python 程序实现汉诺塔

以下是使用 Python 编程语言实现汉诺塔谜题的代码:

示例

立即执行

输出

Enter the number of disks: 3
Move disk 1 from rod A to rod C.
Move disk 2 from rod A to rod B.
Move disk 1 from rod C to rod B.
Move disk 3 from rod A to rod C.
Move disk 1 from rod B to rod A.
Move disk 2 from rod B to rod C.
Move disk 1 from rod A to rod C.

说明

在本例中,我们使用递归函数解决了汉诺塔问题。它将指定数量的盘子从源盘“A”移动到目标盘“C”,使用盘“B”作为辅助。该函数确保一次只移动一个盘子并保持顺序。

结论

汉诺塔谜题是展示递归如何在编程中使用的绝佳示例。在本教程中,我们涵盖了该谜题的所有重要细节、其简单而严格的规则,并使用 Python 实现的递归解决方案。通过将问题分解成更小的子问题,我们能够一步一步地解决整个谜题。

学习无止境。因此,不要止步于此,您可以尝试使用此程序的逻辑来处理更多数量的盘子,并观察它如何随着盘子数量的增加而增加步数。

汉诺塔谜题 Python 实现常见问题解答

1. 什么是汉诺塔谜题?

汉诺塔是一个经典的数学谜题,涉及将一组盘子从一根柱子移动到另一根柱子,遵循三个规则:

  • 一次只能移动一个圆盘。
  • 盘子只能放在较大的盘子或空的柱子上。
  • 只能移动任何柱子最上面的盘子。

2. 递归如何应用于汉诺塔?

递归通过将问题分解为更小的子问题来解决汉诺塔:

  • 将 n-1 个盘子移到辅助盘。
  • 将最大的盘子移到目标盘。
  • 将 n-1 个盘子从辅助盘移到目标盘。

3. 递归函数中的基本情况是什么?

基本情况是当 n == 1 时。此时,只需将一个盘子从源盘移动到目标盘。

4. 用 n 个盘子解决汉诺塔需要多少步?

所需的最少步数是2ⁿ - 1

5. 汉诺塔在学习中的典型用例是什么?

  • 理解递归
  • 基本情况和递归情况分析
  • 算法思维
  • 基于栈的问题