遞歸是指函數直接或間接調用自身的過程。三大特點:
int recursive(int i) {
int sum = 0;
if (0 == i) return 1;
else sum = i * recursive(i - 1);
return sum;
}
簡潔明了,但大數階乘易溢出且效率低,工程中常用迭代或查表優化。
三根柱子,第一根有 64 個盤子(小上大下)。要求移至第三根,規則:每次移一個,小盤必在大盤上。
第 1 個和尚想:找人移 63 個到第 2 柱 → 自己移第 64 個到第 3 柱 → 找人移 63 個從第 2 柱到第 3 柱。
第 2 個和尚同理分解 62 個… 遞推至第 64 個和尚(只需移 1 個,即遞歸出口)。
1→3, 1→2, 3→2 (借助第 3 柱移 2 個到第 2 柱) 1→3 (移第 3 個到第 3 柱) 2→1, 2→3, 1→3 (借助第 1 柱移 2 個從第 2 柱到第 3 柱) 共 7 步 = 2³ - 1
移動 n 個盤子從 A 到 C(借助 B):
#include <stdio.h>
void move(int n, char a, char b) {
printf("Move disk %d from %c to %c\n", n, a, b);
}
void hanoi(int n, char a, char b, char c) {
if (n == 1) move(1, a, c);
else {
hanoi(n-1, a, c, b);
move(n, a, c);
hanoi(n-1, b, a, c);
}
}
int main() {
int num;
scanf("%d", &num);
hanoi(num, 'A', 'B', 'C');
return 0;
}
| 優點 | 缺點 |
|---|---|
| 代碼極度簡潔、邏輯清晰 | 運行效率低(函數調用開銷) |
| 天然適合分治、樹圖遍歷 | 深度過大導致棧溢出 |
| 易於數學歸納法證明正確性 | 可能存在重複計算(需備忘錄優化) |
遞歸是算法設計的核心思想之一,掌握「分解子問題 → 找到出口 → 合併結果」的思維模式,對解決複雜問題至關重要。