遞歸是程式設計中極具優雅性的技術,它允許函數直接或間接地調用自身,將複雜問題分解為相似的子問題。本文通過兩個經典案例——數字累加與素數累加,深入剖析遞歸的實現機制、邊界條件設計以及潛在風險。
最基礎的遞歸範例是計算 1 到 n 的整數和。關鍵在於確立「基準情況」與「遞歸步驟」:
int sum(int n) {
if (n <= 0) return 0;
if (n == 1) return 1;
return n + sum(n - 1);
}
執行流程以 sum(3) 為例:sum(3) → 3 + sum(2) → 3 + (2 + sum(1)) → 3 + 2 + 1 = 6。每層調用都在堆疊中保留狀態,最終回溯求值。
此案例結合了「素數判斷」與「遞歸累加」,展示如何將輔助函數整合進遞歸主流程:
// 判斷素數:是則返回自身,否則返回 0
int judge(int n) {
for (int i = 2; i < n/2 + 1; ++i)
if (n % i == 0) return 0;
return n;
}
// 遞歸累加素數
int sumOfPrime(int n) {
if (n <= 1) return 0;
if (n == 2) return 2;
return judge(n) + sumOfPrime(n - 1);
}
以 sumOfPrime(10) 為例,程式會依次判斷 10、9、8…2 的素數性,累加 2+3+5+7 = 17。注意 judge 函數的優化空間:試除上限可縮減至 √n,並跳過偶數檢查。
優勢:對於漢諾塔、二分查找、快速排序、斐波那契數列等固有遞歸結構的問題,遞歸代碼極度簡潔、易理解。
風險:
遞歸是把雙刃劍:用得好能化繁為簡,用不好則引發災難性後果。掌握其本質,方能駕馭其威力。