C++ 递归经典实战:汉诺塔问题解析
汉诺塔(Tower of Hanoi)是算法学习中绕不开的经典题目,也是理解递归思想的绝佳入口。这道题的核心在于如何将一个复杂的大问题拆解为若干个结构相同的小问题。
核心思路
假设有三根柱子 A、B、C,初始时 A 柱上有 n 个大小不一的盘子,要求将所有盘子移动到 C 柱上,且移动过程中大盘子不能压在小盘子上面。
我们可以从最简单的情况入手推导:
- n = 1:直接将 A 上的盘子移到 C。
- n = 2:先将 1 号盘移到 B,再将 2 号盘移到 C,最后将 1 号盘从 B 移到 C。
- n > 2:策略同上。我们将 A 上方的 n-1 个盘子视为一个整体,先借助 C 柱将它们移到 B 柱;接着将 A 柱剩余的最大盘子直接移到 C 柱;最后将 B 柱上的 n-1 个盘子借助 A 柱移到 C 柱。
这种'将大问题分解为小问题'的过程,正是递归的本质。每次递归调用都在处理规模减一的子任务,直到规模为 1 时直接执行基础操作并返回。
算法流程设计
我们需要设计一个递归函数 dfs,其职责是将指定数量的盘子从一个柱子移动到另一个柱子,利用第三个柱子作为辅助。
- 参数:源柱子
A,目标柱子C,辅助柱子B,当前盘子数量n。 - 终止条件:当
n == 1时,直接将盘子从源柱移到目标柱。 - 递归步骤:
- 将
n-1个盘子从A移到B(此时C作辅助)。 - 将第
n个盘子从A移到C。 - 将
n-1个盘子从B移到C(此时A作辅助)。
- 将
代码实现
下面给出基于 LeetCode 风格的 C++ 实现。注意这里使用 vector<int> 模拟栈结构,back() 获取栈顶,pop_back() 移除栈顶。
class Solution {
public:
// 递归辅助函数:将 n 个盘子从 src 移到 dest,aux 作为中转
void dfs(vector<int>& src, vector<int>& aux, vector<int>& dest, int n) {
if (n == 1) {
// 基准情况:只有一个盘子,直接移动
dest.push_back(src.back());
src.();
;
}
(src, dest, aux, n - );
dest.(src.());
src.();
(aux, src, dest, n - );
}
{
n = A.();
(A, B, C, n);
}
};


