递归思想是一种将复杂问题分解为规模较小的子问题来求解的方法。递归的思考方式就是把大事化小的过程,其中“递”表示递推,“归”表示回归。在书写递归代码时,需要给定限制条件,满足条件时递归停止。
函数递归是指函数自己调用自己的过程。以输入一个数num并按顺序打印为例,我们可以使用递归函数实现:
```c
void Print(int num) {
if (num > 9) // 当num为1位数时跳出if语句
{
Print(num / 10); // 1234/10=123, 123/10=12; 12/10=1;
}
printf("%d ", num % 10); // 1,12%10=2, 123%10=3,1234%10=4.
}
int main() {
int num = 0;
scanf("%d", &num);
Print(num);
return 0;
}
```
在这个例子中,当输入为1234时,使用Print函数实现递归。当num变为1位数时跳出if语句,这一过程就是“递”。接下来开始从后往前计算值。首先打印1,然后打印12%10、123%10、1234%10,最后打印出来的结果是1234。
在上述代码中,我们定义了一个名为factorial的函数,用于计算阶乘。该函数的返回值类型为int。例如,4的阶乘为4 * 3 * 2 * 1,所以当我们输入1时,直接返回1;当我们输入2时,进入else分支返回2 * factorial(n-1)。此时,factorial(n-1)的值为1,因此返回2 * 1。这个结果被ret接收。
然而,递归代码存在一些缺陷。虽然递归代码编写起来相对简单,但在每次调用自身时,都需要在内存中申请新的内存空间。这会导致占用大量内存空间,并可能导致栈溢出。此外,运算量较大。
我们可以通过一个例子来说明这一点:使用递归的方式查找斐波那契数列的位数。以下是相关代码:
```cpp
int seek(int n) {
if (n <= 2) {
return 1;
} else {
return seek(n - 1) + seek(n - 2);
}
}
int main() {
int n = 0;
scanf("%d", &n);
int ret = seek(n);
printf("%d", ret);
}
```
我们知道斐波那契数列为1、1、2、3、5、8等。当查找的位数小于等于2时,结果为1;大于2时,结果为前两个数之和。尽管在此例中,我们可以输入5得到正确的结果,但当输入较大的数时,如45,就很难得到正确答案了。这是因为运算过程较为复杂。
以下是重构后的代码:
```cpp
#include
using namespace std;
int seek(int n) {
int a = 1;
int b = 1;
int c = 1;
while (n > 2) {
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main() {
int n = 0;
cin >> n;
int ret = seek(n);
cout << ret;
return 0;
}
```