初學者常對遞迴「層層呼叫、層層返回」感到困惑。以 `age(n)` 遞迴函數為例,詳細拆解呼叫堆疊、參數傳遞、返回值回傳的完整過程。
int age(int n) {
int c;
if (n == 1) {
c = 10;
cout << n << endl; // 印 1
} else {
c = age(n - 1) + 2;
}
return c;
}
// main 呼叫 age(5)
| 步驟 | 動作 | 堆疊狀態 (顯示 n 值) | 備註 |
|---|---|---|---|
| 1 | main 呼叫 age(5) | [5] | |
| 2 | age(5) 進入,n!=1 → 呼叫 age(4) | [5, 4] | 暫停 age(5),等待 age(4) 返回 |
| 3 | age(4) → 呼叫 age(3) | [5, 4, 3] | |
| 4 | age(3) → 呼叫 age(2) | [5, 4, 3, 2] | |
| 5 | age(2) → 呼叫 age(1) | [5, 4, 3, 2, 1] | |
| 6 | age(1) 滿足基礎情況,**返回 10** | [5, 4, 3, 2] ← 彈出 1 | 印 1,c=10 返回給 age(2) |
| 7 | age(2) 收到 10,**c = 10 + 2 = 12**,返回 12 | [5, 4, 3] ← 彈出 2 | |
| 8 | age(3) 收到 12,**c = 12 + 2 = 14**,返回 14 | [5, 4] ← 彈出 3 | |
| 9 | age(4) 收到 14,**c = 14 + 2 = 16**,返回 16 | [5] ← 彈出 4 | |
| 10 | age(5) 收到 16,**c = 16 + 2 = 18**,返回 18 給 main | [] ← 彈出 5 | 最終結果 18 |
age(1) = 10
age(n) = age(n-1) + 2 (n > 1)
推導:
age(2) = age(1) + 2 = 12
age(3) = age(2) + 2 = 14
age(4) = 16
age(5) = 18
通項:age(n) = 10 + 2*(n-1) = 2n + 8
int age(int n, int depth = 0) {
string indent(depth * 2, ' ');
cout << indent << "-> age(" << n << ")" << endl;
int c;
if (n == 1) { c = 10; }
else { c = age(n-1, depth+1) + 2; }
cout << indent << "<- age(" << n << ") returns " << c << endl;
return c;
}
// 輸出清晰展開/收合過程
| 特性 | 遞迴 | 迭代 |
|---|---|---|
| 可讀性 | 數學定義直觀 | 需手動管理狀態變數 |
| 記憶體 | O(n) 棧空間 | O(1) 常數空間 |
| 效能 | 函數呼叫開銷 | 極快 |
| 適用 | 樹/圖遍歷、分治、動態規劃 | 簡單線性累加 |
理解「向下遞迴拆解問題、向上回溯組裝答案」的雙向流程,配合除錯印出堆疊深度,即可掌握任意遞迴函數的執行邏輯。