递归函数必须有明确的终止条件,否则会导致栈溢出或无限递归;c++不会自动判断终止时机,需手动编写如if(n

递归函数必须有明确的终止条件
写 hanoi 或 fibonacci 时,最常遇到的是栈溢出或无限递归——根本原因不是逻辑错,而是忘了设出口。C++ 不会自动判断“该停了”,你得亲手写 if (n 这类兜底分支。
-
fibonacci的终止条件只能是n == 0或n == 1,写成n 更安全,避免负数输入直接崩 -
hanoi的终止条件是n == 1:只剩一个盘子时,直接从起始柱移到目标柱,不拆解 - 如果用
int算fibonacci(50),结果会溢出,这不是递归问题,是类型选错——改用long long或上std::optional<long long></long>做溢出防护
汉诺塔递归调用顺序不能颠倒
三步移动看似对称,但中间那步(把最大盘子移过去)必须卡在两个递归调用之间,否则逻辑就乱了。很多人抄代码时只改变量名,却把 hanoi(n-1, aux, to, from) 写成 hanoi(n-1, to, aux, from),结果输出一堆无效移动。
- 标准顺序是:
hanoi(n-1, from, aux, to)→ 移大盘 →hanoi(n-1, aux, to, from) - 参数顺序固定为
(盘子数, 起始柱, 目标柱, 辅助柱),记混就会导致辅助柱和目标柱角色错位 - 每轮递归都在换柱子角色,所以传参时不能硬编码
"A"、"B"字符串,而要靠参数传递动态决定
斐波那契递归性能差到不能直接用
fibonacci 的朴素递归时间复杂度是 O(2^n),算 fibonacci(40) 就要几秒,fibonacci(50) 基本卡死。这不是 C++ 慢,是算法本身重复计算太多。
- 比如
fibonacci(5)里,fibonacci(3)被算 3 次,fibonacci(2)被算 5 次 - 加个
static std::unordered_map<int long> memo</int>缓存结果,能压到O(n),但要注意线程不安全 - 真要高性能,别碰递归——直接写循环版,3 行搞定,还省栈空间
递归深度超限怎么办
默认栈空间撑不住深度递归,尤其 Windows 下默认 1MB 栈,hanoi(20) 就可能崩,fibonacci(1000) 必崩。这不是代码写错了,是环境限制。
立即学习“C++免费学习笔记(深入)”;
- g++ 可用
-Wstack-protector提前预警,运行时加ulimit -s 65536(Linux)临时扩栈 - Windows 下用
/STACK:8388608链接器选项把栈提到 8MB - 更稳妥的做法是手动转迭代:汉诺塔可用栈模拟递归过程,斐波那契用两个变量滚动更新
递归看起来简洁,但 C++ 里它是个带隐式成本的操作——栈帧开销、无尾递归优化、调试时堆栈难读。真正上线的代码,往往第一版递归,第二版就重写成迭代了。










