# 基本觀念
遞迴同數學的遞迴,都需要找到關係式,並且每個在範圍內的正整數都必須要對應一個值。
以費式數列為例,一個費式數列如下
$[1,1,2,3,5,8,……,F(n-1)+F(n-2)]$
我們可以定義一個關係式
$$
F[n]=\begin{cases}
F[0]=F[1]=1
\\[2ex]
F[n]=F[n-1]+F[n-2]
\end{cases}
$$
# 用法
## 範例程式碼
```cpp=
#include <bits/stdc++.h>
using namespace std;
int h;
int f(int x)
{
if(x>10)
return x;
else
return f(x+1);
}
void d(int x,int y)
{
if(x>y)
{
h++;
return;
}
return;
}
void g()
{
if(h>0)
{
h--;
return;
}
return;
}
int main() {
int a=10,b=50,c=10;
h=0;
cout<<f(a)<<endl;
d(b,a);
cout<<h<<endl;
g();
cout<<h<<endl;
return 0;
}
```
## 解析
### f
以第4行為例
```cpp=
int f(int x)
```
:::info
前面的 **"int"** 表示 **"回傳"** 東西的型態
中間的 **"f"** 表示這個函式稱為 **"f"**
後面的 **"int x"** 表示這個函式需要 **"輸入"** 的一個值
:::
4到10行可以視為是一整個區塊
```cpp=
int f(int x)
{
if(x>10)
return x;
else
return f(x+1);
}
```
整個區塊的流程為
:::warning
$1. 輸入一個x$
$2. 如果x大於10 回傳x$
$3. 否則x+1直到x>10$
:::
### d
```cpp=
void d(int x,int y)
{
if(x>y)
{
h++;
return;
}
return;
}
```
以這個區塊來看
:::success
**型態=>void
名字=>d
輸入=>x,y**
:::
這裡有兩個重點
:::info
**void**
```
void(N.) 空洞;空間;空白(From Cambridge)
```
而這裡void便是表示回傳值為空,也就是**沒有**回傳值。
:::
:::info
**兩個輸入值**
對,兩個輸入就是得這樣,沒有為什麼。
:::
### g
```cpp=
void g()
{
if(h>0)
{
h--;
return;
}
return;
}
```
以這個區塊來看
:::success
**型態=>void
名字=>g
輸入=>???**
:::
事實上,這裡**不須要**任何輸入,直接呼叫即可。
### 變數
首先,每個區塊裡的變數都**不會**共用,所以f裡面的x跟d裡面的x是**不同的**x。
假使你需要一個每個區塊都可以使用的變數,在這個程式中就是h,你只需要宣告在所有程式碼區塊前即可。
## 流程
首先,程式碼必然是先從main開始,**一個程式只能有一個main**,這是規則,~~不能打破(梗)~~。
```cpp=
int main() {
int a=10,b=50,c=10;
h=0;
cout<<f(a)<<endl;
d(b,a);
cout<<h<<endl;
g();
cout<<h<<endl;
return 0;
}
```
假如是有回傳值的函數,例如f,可以指定給變數或是直接輸出,假如是無回傳值的函數,例如d,g,則**不可**指定給變數或是直接輸出,因為沒有回傳值。
(呼叫方法即為程式碼內容)
# 總結
遞迴在使用時複雜度是呈現指數型上升的,在未來,我們會利用動態規劃來優化這部分的複雜度,費式數列或階層的運算會有更好的解法。