目录
概念
无限直接或间接调用自身函数,每次调用会改变一个关键变量,直至这个关键变量不符合判断条件,此后不再调用
主要思考方式:大事化小,把复杂的问题层层转化成与原问题相似的规模较小的问题
递归的三大要素
- 明确函数功能
- 存在递归结束条件,每次调用之后越来越接近结束条件,明确参数是什么时,递归结束,返回结果,这个时候能直接根据参数的值得到函数结果。
- 找出函数的等价关系式,例如求阶乘f(n) = f(n-1) * n
栈溢出
程序向栈中某个变量写入的字节数,超过了这个变量所能申请的字节数,导致栈中与其相邻变量的值被改变。
练习
1.接受一个无符号整型,打印它的每一位
#include <stdio.h>
// 1. 明确函数功能: 逐个打印一个数的每一位
// 2. 终止条件:只有一位后终止,不满足条件 (n > 9) 后终止运行
// 3. 明确最小规模的函数值:当 (n <= 9),递归结束,后返回最后一个函数值
// 3. 等价关系式:n / 10 --> n % 10 --> n / 10 --> n % 10 ...
void print(unsigned int n)
{ if (n > 9)
{
print(n / 10);
}
printf("%d ",n % 10);
}
int main()
{
unsigned int num;
scanf("%d", &num);
print(num);
return 0;
}
- 程序执行流程图
2. 编写函数,不允许创建临时变量,打印字符串长度
// 函数功能:打印字符串长度
// 终止条件:指针向后移,遇到'\0'后结束移动
// 当指针指向'\0'时, return 0
// 等价关系式:1 + str_length(n + 1)
#include <stdio.h>
int str_length(char *n)
{
if (*n != '\0')
{
return 1 + str_length(n + 1);
}
else
{
return 0;
}
}
int main()
{
char arr[] = "qwertyui";
int re = str_length(arr);
printf("%d\n", re);
return 0;
}
- 程序执行流程图
3.打印n的阶乘
//函数功能:打印n! 4!=1*2*3*4
//终止条件:n == 1, return 1
//等价关系式:f(n) = n * f(n-1)
#include <stdio.h>
int factorial(int n)
{
if (n != 1)
{
return n * factorial(n - 1);
}
else
{
return 1;
}
}
int main()
{
int n;
scanf("%d", &n);
int re = factorial(n);
printf("%d\n", re);
return 0;
}
- 程序执行流程图
4.斐波那契数列
// 斐波那契数列 1 1 2 3 5 8 13 21.... a b c
//函数功能:打印斐波那契数字
//终止条件:n <= 2 return 1
//等价关系式 Fib(n - 1) + Fib(n - 2);
#include <stdio.h>
int Fib(int n)
{
if (n <= 2)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
int main()
{
int num;
scanf("%d", &num);
int re = Fib(num);
printf("%d", re);
return 0;
}
- 程序执行流程图
5 为避免栈溢出,可将递归改成非递归,比如循环的方式实现
5.1 fib
#include <stdio.h>
int Fib(int n)
{
int pre_re = 1;
int next_re = 1;
int lat_re = 1;
for (; n > 2;)
{
n--;
pre_re = next_re;
next_re = lat_re;
lat_re = pre_re + lat_re;
}
return lat_re;
}
int main()
{
int num;
scanf("%d", &num);
int re = Fib(num);
printf("%d", re);
return 0;
}
- 程序执行流程图
5.2 n!
#include <stdio.h>
int Factorical(int m)
{
int a = 1;
int assum = 1;
for (a = 1; a <= m; a++)
{
assum *= a;
}
return assum;
}
int main()
{
int n;
scanf("%d", &n);
int re = Factorical(n);
printf("%d\n", re);
return 0;
}