問題描述 (同 C 版)
5 人坐一排。第 5 人比第 4 人大 2 歲... 第 1 人 10 歲。求第 5 人年齡。
Java 遞歸實現
public class AgeRecursion {
// 遞歸函數
static int getAge(int n) {
if (n == 1) return 10; // 基線條件
return 2 + getAge(n - 1); // 遞歸步驟
}
public static void main(String[] args) {
System.out.println("第 5 人年齡: " + getAge(5)); // 18
}
}
C vs Java 對比
| 維度 | C 語言版 | Java 版 |
| 函數聲明 | static int getAge(int n) | static int getAge(int n) |
| 主函數 | int main() | public static void main(String[] args) |
| 輸出 | printf("%d", getAge(5)) | System.out.println(getAge(5)) |
| 類型安全 | 隱式 int | 強類型 |
| 棧溢出保護 | 無 | StackOverflowError 異常 |
遞歸 vs 迭代 vs 公式
// 迭代
int getAgeIter(int n) {
int age = 10;
for (int i = 2; i <= n; i++) age += 2;
return age;
}
// 閉式公式
int getAgeFormula(int n) {
return 10 + 2 * (n - 1);
}
遞歸深度與棧安全
- 本例深度 5,完全安全
- Java 默認棧大小 ~1MB,每幀 ~1KB → 支援 ~1000 層遞歸
- 超過拋出
StackOverflowError (Error 而非 Exception,通常不捕獲)
- 可用
-Xss2m 增大棧,但治標不治本
現代 Java 函數式寫法
import java.util.stream.IntStream;
public class AgeFunctional {
public static void main(String[] args) {
// 迭代流
int age = IntStream.iterate(10, a -> a + 2)
.skip(4) // 跳過前 4 項 (第1人已知)
.findFirst()
.orElse(10);
System.out.println(age); // 18
// 或簡單 reduce
int age2 = IntStream.rangeClosed(2, 5)
.reduce(10, (a, i) -> a + 2);
}
}
總結
五人年齡是線性遞歸最簡形式:單分支、單遞歸調用、常數縮小。Java 版與 C 版邏輯同構,語法差異僅在 boilerplate。教學價值:建立「基線→縮小→組合」遞歸思維模型。實際開發中,此類線性遞歸**優先改寫為迭代或公式**,避免棧開銷、調試困難、無尾調用優化等問題。
- 上一篇文章: Java 遞歸計算階乘:5! 遞歸實現與棧幀分析
- 下一篇文章: Java 位數統計與逆序輸出:不超過 5 位正整數處理
Copyright ©
程式碼之家 All Rights Reserved