- Python
汉诺塔
- 2025-4-9 19:25:34 @
汉诺塔问题介绍
汉诺塔是一个源于印度古老传说的益智问题。有三根柱子(假设分别为A柱、B柱、C柱 ),A柱上从下往上按照大小顺序摞着若干个圆盘。游戏目标是把A柱上的圆盘按同样大小顺序重新摆放到C柱上,并且规定:
- 每次只能移动一个圆盘。
- 在小圆盘上不能放大圆盘,即任何时刻大圆盘不能压在小圆盘上面。
- 可以借助B柱来辅助移动圆盘。
代码实现思路
可以使用递归的方法来解决汉诺塔问题。递归就是函数自己调用自己。基本思路如下:
- 把
n - 1
个圆盘从A柱借助C柱移动到B柱 (这是一个子问题,规模变小了 )。 - 把第
n
个(也就是最下面最大的 )圆盘从A柱直接移动到C柱。 - 再把B柱上的
n - 1
个圆盘借助A柱移动到C柱 (又是一个类似的子问题 )。
Python代码及注释
def hanoi(n, source, target, auxiliary):
"""
汉诺塔递归函数
:param n: 圆盘的个数
:param source: 源柱子(开始时圆盘所在柱子)
:param target: 目标柱子(最终圆盘要移动到的柱子)
:param auxiliary: 辅助柱子(用来辅助移动圆盘的柱子)
"""
if n == 1:
# 当只有一个圆盘时,直接从源柱子移动到目标柱子
print(f"Move disk 1 from {source} to {target}")
return
# 把n - 1个圆盘从源柱子借助目标柱子移动到辅助柱子
hanoi(n - 1, source, auxiliary, target)
print(f"Move disk {n} from {source} to {target}")
# 把n - 1个圆盘从辅助柱子借助源柱子移动到目标柱子
hanoi(n - 1, auxiliary, target, source)
代码调用示例
# 假设有3个圆盘,A柱为源柱子,C柱为目标柱子,B柱为辅助柱子
hanoi(3, 'A', 'C', 'B')
代码解释
- 函数
hanoi
定义了汉诺塔问题的解决逻辑。它接收4个参数,n
代表圆盘数量,source
是起始柱子,target
是目标柱子,auxiliary
是辅助柱子。 - 当
n == 1
时,这是递归的终止条件,因为只有一个圆盘,直接把它从源柱子移动到目标柱子并打印移动步骤即可。 - 对于
n > 1
的情况,先递归调用hanoi
函数把n - 1
个圆盘从源柱子借助目标柱子移动到辅助柱子,然后打印把第n
个圆盘从源柱子移动到目标柱子的步骤,最后再递归调用hanoi
函数把辅助柱子上的n - 1
个圆盘借助源柱子移动到目标柱子。
这样,通过递归的方式就可以解决汉诺塔问题,并且打印出每一步的移动操作。
4 条评论
-
admin SU @ 2025-4-9 20:21:30已修改
def hanoi(n, source, target, auxiliary): """ 汉诺塔递归函数 :param n: 圆盘的个数 :param source: 源柱子(开始时圆盘所在柱子) :param target: 目标柱子(最终圆盘要移动到的柱子) :param auxiliary: 辅助柱子(用来辅助移动圆盘的柱子) """ if n == 1: # 当只有一个圆盘时,直接从源柱子移动到目标柱子 print(f"将 1 号盘从 {source} 到 {target}") return # 把n - 1个圆盘从源柱子借助目标柱子移动到辅助柱子 hanoi(n - 1, source, auxiliary, target) print(f"将 {n} 号盘从 {source} 到 {target}") # 把n - 1个圆盘从辅助柱子借助源柱子移动到目标柱子 hanoi(n - 1, auxiliary, target, source) # 假设有3个圆盘,A柱为源柱子,C柱为目标柱子,B柱为辅助柱子 #hanoi(3, 'A', 'C', 'B') hanoi(3, '第一个柱子', '第三个柱子', '第二个柱子')
-
2025-4-9 19:43:51@
-
2025-4-9 19:26:00@
汉诺塔问题概述
汉诺塔问题是一个经典的递归问题,有三根柱子(通常标记为A、B、C),在柱子A上有若干个大小不同的圆盘,要求把这些圆盘从柱子A移动到柱子C,且移动过程需遵循以下规则:
- 每次只能移动一个圆盘。
- 任何时候大圆盘都不能放在小圆盘上面。
递推关系分析
设移动
n
个圆盘所需的最少步数为 。- 初始情况:当 时,只需要将这一个圆盘从起始柱直接移动到目标柱,所以 。
- 递推情况:当有 个圆盘时,可以把移动过程分为三个步骤:
- 把上面的 个圆盘从起始柱借助目标柱移动到辅助柱,这一步需要的步数是 。
- 把最下面的第 个圆盘从起始柱移动到目标柱,这一步需要 步。
- 把辅助柱上的 个圆盘借助起始柱移动到目标柱,这一步又需要 步。
因此,得到递推公式 。
通项公式推导
对递推公式 进行变形求解通项公式:
- 设 ,展开可得 。
- 对比 ,可知 。
- 那么数列 是以 为首项, 为公比的等比数列。
- 根据等比数列通项公式 (这里 ,,),可得 。
- 所以,。
Python 代码实现
下面是用 Python 实现根据通项公式计算移动
n
个圆盘所需最少步数的代码:# 定义一个函数,接收圆盘数量 n 作为参数 def hanoi_steps(n): # 根据通项公式 2^n - 1 计算移动 n 个圆盘所需的最少步数 return 2 ** n - 1 # 示例:计算移动 3 个圆盘所需的最少步数 n = 3 # 调用函数计算结果 steps = hanoi_steps(n) print(f"移动 {n} 个圆盘最少需要 {steps} 步。")
代码解释
hanoi_steps
函数接收一个整数参数n
,代表圆盘的数量。- 在函数内部,使用
2 ** n - 1
计算移动n
个圆盘所需的最少步数,其中2 ** n
表示 2 的n
次方。 - 最后通过示例,计算并输出移动 3 个圆盘所需的最少步数。你可以修改
n
的值来计算不同数量圆盘的最少移动步数。
- 1