- 代码
# 不使用递归
def hanoi(n):
tower_belong = [0] * n # 用列表开辟 n 个空间,用于存放 n 个金片各自的编号,编号对应塔号
# 金片移动,编号对应更改
if n % 2 == 0: # 金片的编号对应这里的塔号
tower_name = ['A', 'B', 'C'] # 若 n 为偶数,最终所有金片恰好能移到 C 塔
else:
tower_name = ['A', 'C', 'B'] # 若 n 为奇数,最终所有金片会移到 B 塔
# 用“轮换对称”将 B、C 两塔互换名字,以实现“负负得正”
for step in range(1, 2**n): # n 片金片最少需要移动 2^n - 1 次
bin_step = bin(step) # 求得 step 的二进制数值
gold_num = len(bin_step) - bin_step.rfind('1') - 1
# 计算 step 末尾 0 的个数,得到金片编号
# 如 step = 0b0001,则 step 末尾 0 的个数为 0,表示此刻应移动 0 号金片
# 如 step = 0b0100,则 step 末尾 0 的个数为 2,表示此刻应移动 2 号金片,依此类推
print('第', str(step), '步:移动', str(gold_num), '号塔,从', \
tower_name[tower_belong[gold_num]], '到', end=' ') # 移出金片的塔
if gold_num % 2 == 0: # 若 num 为 偶数,则右移
tower_belong[gold_num] = (tower_belong[gold_num] + 1) % 3
# 若从 C 塔右移,则又回到了 A 塔
else: # 若 num 为奇数,则左移
tower_belong[gold_num] = (tower_belong[gold_num] + 2) % 3
# 若从 A 塔左移,则又去到了 C 塔
print(tower_name[tower_belong[gold_num]]) # 移入金片的塔
- 运行情况
-
3 层汉诺塔
hanoi(3)
第 1 步:移动 0 号金片,从 A 到 C
第 2 步:移动 1 号金片,从 A 到 B
第 3 步:移动 0 号金片,从 C 到 B
第 4 步:移动 2 号金片,从 A 到 C
第 5 步:移动 0 号金片,从 B 到 A
第 6 步:移动 1 号金片,从 B 到 C
第 7 步:移动 0 号金片,从 A 到 C