喜欢这个游戏吗?匿名投票,一秒钟

0 条讨论

通关了吗?留个最少步数记录
还没有人留言来写第一条——你想问的,多半也是别人想问的

汉诺塔 · Tower of Hanoi

汉诺塔是经典的递归算法教学工具,也是一个优雅的数学谜题。将所有圆盘从起点柱移到终点柱,每次只能移动一个盘,且大盘不能放在小盘上方。这个在线版本支持 3-6 层难度,每一步都配有递归算法解读,帮助你真正理解递归思维。

游戏特色

1

4 档难度

3 盘入门(7步)→ 6 盘挑战(63步),循序渐进掌握递归思维。

2

递归解读

每移动一步,下方都会出现这一步在递归调用树中的位置和意义。

3

最优解演示

一键观看 AI 演示最优解法,支持慢/中/快三档速度,可暂停回看。

4

效率评分

实时计算你的步数与最优解的比率,挑战 100% 完美通关。

递归算法原理

什么是递归

递归是一种解决问题的方法:把一个大问题拆成结构相同但规模更小的子问题,直到小到可以直接解决。想象俄罗斯套娃——打开一个,里面还有一个,直到最小的那个。汉诺塔是理解递归最直观的例子,因为它的问题结构天然就是递归的。

递归有两个要素:基础情形(最小的套娃,直接处理)和递归步骤(打开当前套娃,处理里面更小的)。如果缺少基础情形,递归会无限循环下去——就像永远打不完的套娃。

汉诺塔的递归拆解

要把 n 个盘从 A 柱移到 C 柱,你面对的核心矛盾是:最大的盘被压在最下面,上面所有盘不搬走它就动不了。于是解法自然浮现——

hanoi(n, 起点, 终点, 中转):

if n == 1: move(起点 → 终点) // 基础情形:只有1个盘,直接移

else:

hanoi(n-1, 起点, 中转, 终点) // ① 把上面 n-1 个盘搬到中转柱

move(起点 → 终点) // ② 最大盘直接移到终点

hanoi(n-1, 中转, 终点, 起点) // ③ n-1 个盘从中转搬到终点

关键洞察:步骤 ① 和 ③ 跟原问题结构完全一样,只是规模少了一个盘、柱子角色互换了。这就是递归——你不需要知道 n-1 个盘怎么搬,你只需要相信它能搬好(递归信仰之跃),然后处理当前层的那一个盘就行。

3 个盘的完整递归过程

以 3 个盘(A→C)为例,递归展开后的 7 步移动:

hanoi(3, A→C, 中转B)

├─ hanoi(2, A→B, 中转C)

│ ├─ hanoi(1, A→C) → 步骤1: A→C 移动盘1

│ ├─ 步骤2: A→B 移动盘2

│ └─ hanoi(1, C→B) → 步骤3: C→B 移动盘1

├─ 步骤4: A→C 移动盘3(最大盘!)

└─ hanoi(2, B→C, 中转A)

├─ hanoi(1, B→A) → 步骤5: B→A 移动盘1

├─ 步骤6: B→C 移动盘2

└─ hanoi(1, A→C) → 步骤7: A→C 移动盘1

注意对称性:步骤 1-3 把上面 2 个盘搬到 B 柱,步骤 4 搬最大盘,步骤 5-7 再把 2 个盘从 B 搬到 C。前半段和后半段结构完全相同,只是柱子角色对调了。

递归与调用栈

计算机执行递归时,每次调用函数都会在内存中创建一个「栈帧」,记录当前执行到哪里、参数是什么。当递归深入时栈帧不断堆叠,触底(基础情形)后再一层层返回。

调用栈变化(3 盘,执行到步骤 1 时):

┌─────────────────────────────┐

│ hanoi(1, A→C) │ ← 栈顶:当前执行

├─────────────────────────────┤

│ hanoi(2, A→B, 中转C) 步骤① │ ← 等待子调用返回

├─────────────────────────────┤

│ hanoi(3, A→C, 中转B) 步骤① │ ← 等待子调用返回

└─────────────────────────────┘

栈的最大深度等于盘的数量 n。这就是递归的空间代价——n 个盘需要 n 层栈帧。对于汉诺塔来说 n 很小(通常不超过 20),完全不是问题。但在其他场景中,递归过深会导致「栈溢出」(Stack Overflow)。

递归 vs 迭代

汉诺塔也可以用迭代(循环)来解,不需要递归。迭代解法基于一个巧妙的规律:

规律1

最小盘每隔一步移动一次,方向固定(n 为奇数时逆时针 A→C→B→A,n 为偶数时顺时针 A→B→C→A)

规律2

非最小盘的移动步只有一种合法选择(因为另一个柱子上要么没盘,要么顶部盘更小)

递归迭代
代码量5 行,极简15-20 行
可读性直观,与问题结构一致需要理解移动规律
空间O(n) 栈空间O(1) 常数空间
时间O(2ⁿ)O(2ⁿ),相同

两种方法步数完全一样,区别在于思维方式。递归是「自顶向下」的分解思维,迭代是「自底向上」的规律发现。对于汉诺塔,递归解法更自然、更容易理解和证明正确性。

传说与指数增长的威力

汉诺塔的起源是一个传说:在印度贝拿勒斯的神庙中,僧侣们正在移动一组 64 个金盘。当所有盘移动完成时,世界将会终结。

这个传说恰好揭示了指数增长的惊人威力。64 个盘需要多少步?

2⁶⁴ - 1 = 18,446,744,073,709,551,615 步

假设每秒移动一个盘,需要约 5845 亿年——是宇宙年龄(138 亿年)的 42 倍。

这就是为什么理解 2ⁿ 增长如此重要。从 6 盘的 63 步到 64 盘的 1800 亿亿步,每多一个盘步数翻倍。递归让你用 5 行代码描述这个解法,但宇宙的寿命都不够执行完。算法的时间复杂度,才是真正的瓶颈。

为什么最少步数是 2ⁿ - 1

从递归结构直接可以推导出步数公式。设 T(n) 为 n 个盘的最少步数:

T(1) = 1

T(n) = T(n-1) + 1 + T(n-1) = 2·T(n-1) + 1

展开这个递推式:T(n) = 2·T(n-1) + 1 = 2·(2·T(n-2) + 1) + 1 = ... = 2ⁿ - 1。

3 盘
7 步
4 盘
15 步
5 盘
31 步
6 盘
63 步

常见问题

汉诺塔的最少步数是多少?+

汉诺塔的最少步数为 2^n - 1,其中 n 是圆盘数量。3个盘最少7步,4个盘15步,5个盘31步,6个盘63步。这是数学证明的绝对下界,不可能更少。

大盘不能压小盘的规则有什么数学意义?+

这个约束正是汉诺塔全部复杂性的来源。去掉这条规则,问题立刻变得微不足道(直接搬就行)。正是因为这个限制,才产生了递归结构——你必须先把上面的盘搬走,才能动下面的盘。

怎样才能达到100%效率?+

需要每一步都走最优解的路径。关键策略:最小盘始终往同一个方向轮转(3盘时逆时针,4盘时顺时针),非最小盘永远只有一种合法移动。掌握这个规律就能达到完美解。

最优解演示的算法是什么?+

使用经典的递归算法:hanoi(n, from, to, via)。当 n=1 时直接移动(基础情形),否则先递归移动上面 n-1 个盘到中转柱,再移动最大盘到目标柱,最后递归移动 n-1 个盘到目标柱。

关于这个游戏

汉诺塔是「好玩的游戏」系列中的经典益智游戏。如果你喜欢,欢迎在 X 上分享你的通关截图。