函数递归
什么是函数递呢
函数递归是常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,而且只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量
递归的主要思考方式是在于:把大事化小
递归的必要条件
- 限制条件,意思是当程序满足条件时,递归停止
- 每次递归调用后,会慢慢接近限制条件
递归的必要条件不能没有,没有就会变成死递归
例如:
公园里的卖圈圈套公仔
当你出钱和老板买完(这相当于主函数进入递归)
游戏的结束条件是将手中的圈圈丢完(限制条件)
手中的圈圈相当于可以递归的次数,每丢一次都会接近限制条件
可能你还不太明白,那在来个例子,大家大概都玩过娃娃机吧
你投币(进入递归)
抓取娃娃的次数(限制条件)
每一次抓取(接近限制条件)
下面来练习一下,加深印象
练习递归
练习题 1:
接受一个整型值(无符号),按照顺序打印它的每一位
例如:
输入 1234
输出 1 2 3 4
void print(int n)
{
if (n > 9) 限制条件
{
print(n / 10); 接近限制条件
}
printf("%d ", n % 10);
}
int main()
{
int n = 1234;
print(n);
return 0;
}
思路图解
看下图执行流程
好,懂了看下一题
练习题 2:
编写函数不允许创建临时变量,求字符串的长度
咱们正常的函数写法思路是:
arr 数组传数组首元素地址给 str ,str 不等于 \0 时,n++判断字符的个数,然后不断的循环直到找到 ‘\0’
但是这种方法使用了临时变量
int my_strlen(char* str)
{
int n = 0;
while(*str != '\0')
{
n++;
*str++;
}
return n;
}
int main()
{
char arr[] = { "abcf" };
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
但是以递归的方式呢?
解题思路:
假设第一个字符不是 \0 ,那么它的长度至少是 1
那么 my_strlen就可以拆分
my_strlen “abcf”
1+ my_strlen " abc"
1+1+ my_strlen “ab”
1+1+1+ my_strlen “a”
1+1+1+1 + my_strlen" "
就变成了 1+1+1+1+0
代码实现:
int my_strlen(char* str)
{
if (*str != '\0')
return 1 + my_strlen(str + 1);
else
return 0;
}
int main()
{
char arr[] = { "abc" };
int ret = my_strlen(arr);
printf("%d\n", ret);
return 0;
}
思路图解
看下图执行流程
练习题 3:
求n的阶乘(不考虑溢出)
n如果小于等于 1 的时候直接返回1,1*1=1
代码实现:
int fac(int n)
{
if (n <= 1)
return 1;
else
return n * fac(n - 1);
}
int main()
{
int n = 5;
int ret = fac(n);
printf("%d", ret);
return 0;
}
思路图解
看下图执行流程
练习题 4:
求第n个斐波那契数(不考虑溢出)
斐波那契数
1 1 2 3 5 8 13 21 34 55 …
斐波那契数规律是前二个数加起来就是第三个数的值
代码实现:
int Fib(int n)
{
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
return 0;
}
用递归的方式在求解的数值过大时,特别耗时,函数在调用的过程中很多计算其实在一直重复
在调试 fbi 函数的时候,如果你的参数比较大,那就会报错:stack overflow(栈溢出)
系统分配给程序的栈空间是有限的,但是如果出现了死循环,或者(死递归),这样有可能导致一
直开辟栈空间,最终产生栈空间耗尽的情况,这样的现象我们称为栈溢出
出现这种情况后,就不要用递归的方式来写了
非递归的方式来实现:
int fun(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n >= 3)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int a = 10;
printf("%d", fun(a));
return 0;
}