
本文详解如何修改递归斐波那契函数,使其在每次递归返回时精确打印当前层级的计算结果,从而输出符合调用栈展开顺序的完整过程日志,仅需一个 System.out.println 语句且不改变算法逻辑。
本文详解如何修改递归斐波那契函数,使其在每次递归返回时精确打印当前层级的计算结果,从而输出符合调用栈展开顺序的完整过程日志,仅需一个 `system.out.println` 语句且不改变算法逻辑。
要实现题目中要求的输出效果——即按实际递归调用完成的先后顺序,逐行打印形如 Fib(1) is: 1 的日志——关键在于将打印语句放在递归返回之后、函数返回之前的位置,而非嵌套在条件分支内部。
观察原始代码的问题:
- 原写法在
else分支中重复调用了recFib(n-1) + recFib(n-2)两次(一次用于计算,一次用于返回),不仅低效,更导致无法在正确时机捕获并打印n对应的结果; - 若把
println放在if或else内部,会因递归未完成而提前打印,或遗漏某些层级的输出。
✅ 正确解法是:统一计算 result,再统一打印,最后统一返回。这样可确保每个 n 值对应的结果在它所依赖的所有子问题(n-1 和 n-2)均已计算并打印完毕后,才被打印和返回——这恰好匹配深度优先、自底向上的递归回溯顺序。
以下是修正后的完整可运行代码:
public class Test {
public static void main(String[] args) {
Fibonacci fib = new Fibonacci();
System.out.println("Rec results is ");
fib.recFib(5);
}
}
class Fibonacci {
public int recFib(int n) {
int result;
if (n <p>? <strong>执行逻辑说明(以 <code>recFib(3)</code> 为例)</strong>: </p><ol>
<li>
<code>recFib(3)</code> → 调用 <code>recFib(2)</code> 和 <code>recFib(1)</code>; </li>
<li>
<code>recFib(2)</code> → 先调用 <code>recFib(1)</code>(打印 <code>Fib(1) is: 1</code>),再调用 <code>recFib(0)</code>(打印 <code>Fib(0) is: 0</code>),然后计算 <code>result = 1</code> 并打印 <code>Fib(2) is: 1</code>; </li>
<li>
<code>recFib(1)</code> → 直接返回 <code>1</code>,打印 <code>Fib(1) is: 1</code>; </li>
<li>最后 <code>recFib(3)</code> 得到 <code>1 + 1 = 2</code>,打印 <code>Fib(3) is: 2</code>。 </li>
</ol><p>✅ 输出严格遵循「子问题先完成、父问题后打印」的自然递归流,与题设示例完全一致。</p><p>⚠️ <strong>注意事项</strong>: </p>
- 此方案仅使用一个
println语句,满足题目约束; - 不可将
println移入if/else内部,否则会破坏执行顺序或造成重复计算; - 若需避免
n=0和n=1的冗余打印(如仅关注n≥2的结果),可在打印前加条件判断,但本题明确要求完整展示所有递归节点,故无需过滤。
掌握这一模式,有助于深入理解递归的执行时序与调用栈行为,是调试和教学递归算法的重要实践技巧。










