---
# System prepended metadata

title: C++_遞迴

---

# 遞迴

## 1. 什麼是遞迴？
遞迴（Recursion）是一種程式設計技巧，函式會在其內部直接或間接呼叫自己。適用於問題可拆解為較小的相同問題，如數學計算、搜尋與排序。

## 2. 遞迴函式的結構
```cpp=
返回類型 函式名稱(參數) {
    // 終止條件
    if (條件滿足) {
        return 結果;
    }
    // 遞迴呼叫
    return 函式名稱(新參數);
}
```
**終止條件：** 確保遞迴不會無限執行，一定要加，不然妳可以試試，~~放心不會試試就逝世~~。
**遞迴步驟：** 逐步將問題縮小，直到符合終止條件。

## 3. 遞迴範例
### 費氏數列
#### 什麼是**費式數列**
由數學家**列昂納多·費波那契**（Leonardo Fibonacci）提出的數列，其特點是**每一項數字**都是**前兩項數字的和**。這個數列通常以 0 和 1 開始，之後的數字依照規則生成。

數列的數字如下所示： $0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...$

費式數列的定義：
$F(0) = 0$

$F(1) = 1$

$F(n) = F(n-1) + F(n-2) (n ≥ 2)$

##### 特點：
每個數字都是前兩個數字的和。
#### eg. 

```cpp=
#include <iostream>
using namespace std;

int f(int n) {
    if (n <= 1) return n;  // 終止條件
    return f(n - 1) + f(n - 2);  // 遞迴步驟
}

int main() {
    int n = 5;
    cout << "F(n) = " << f(n) << endl;
    return 0;
}
```
** 輸出：**
```
F(5) = 5
```

### 階乘計算
這我應該不用多說吧!!
```cpp
#include <iostream>
using namespace std;

int f(int n) {
    if (n == 0) return 1;  // 終止條件
    return n * f(n - 1);  // 遞迴步驟
}

int main() {
    int n = 5;
    cout << "F(n) = " << f(n) << endl;
    return 0;
}
```
** 輸出：**
```
F(5) = 120
```

## 4. 遞迴與迴圈的比較
| 比較項目 | 遞迴 | 迴圈 |
|----------|------|------|
| 可讀性 | 適合數學遞推問題 | 適合重複執行的邏輯 |
| 記憶體使用 | 可能較高（因為使用堆疊） | 佔用較少記憶體 |
| 效率 | 可能較低（函式呼叫有額外開銷） | 通常較快 |

## 5. 遞迴的應用
- **數學運算**：費氏數列、階乘、歐幾里得算法，甚至是河內塔問題都可以。
- **資料結構**：樹（Tree）、圖（Graph）的遍歷。
- **演算法**：合併排序（Merge Sort）、快速排序（Quick Sort）。

## 6. 結論
遞迴是一種強大的程式設計工具，適合解決可拆解為較小子問題的情境。但是，如果沒有妥善設定終止條件，可能導致無窮遞迴與記憶體溢位（Stack Overflow）。適時選擇迴圈或遞迴，能夠提升程式的效能與可讀性。

:::success
上面提到的 Stack Overflow 在記憶體分布有做介紹，他和資料結構的 stack 沒有什麼太大關係，所以不要誤會了。
:::
