❤️坚持是一种品质❤️

🧓作者:每天都要记得刷题(●’◡’●)
🍉时间:2022/04/04
🍉本篇感悟:举一反三,由求 n的阶乘联想到递归求n个数中的最大值,对递归有了更深的了解。

文章目录

  • ​​⭐题目(代码😇在文末)​​
  • ​​⭐递归思想​​
  • ​​⭐求前n个斐波那契数​​
  • ​​⭐具体代码(答案😇)​​

⭐题目(代码😇在文末)

使用递归求 55 ,22, 155, 77, 99这5个数中的最大值

⭐递归思想

【递归】递归求n个数中的最大值_函数调用

🎈Q: 什么是递归?
A1:我们学过函数,知道了函数调用,函数调用就是一个函数调用其他函数,比如主函数调用求两个数之和。
A2:递归就是一个函数调用自身,例如主函数调用主函数(这就是最简单的函数递归,但是会造成死循环,不建议这末做)

#include<stdio.h>
int main()
{
printf("我现在知道递归是什么了");
main();
return 0;
}

死循环了,代码如下:

【递归】递归求n个数中的最大值_函数调用_02

🎈递归递归:有递有归,先递后归

以4的阶乘为例:
4!
递:4 递:3 递:2 递;1
归:1 归:2 归:6 归;24

🎈 利器1:递推公式(数学公式)

【递归】递归求n个数中的最大值_c语言_03

🎈利器2:递推栈图:

【递归】递归求n个数中的最大值_函数调用_04

🎈利器三:把求解的任务重复(大问题化为类似的子问题)
递归出口:最后一次递归,此时的函数值是可以直接算出,不需要递归求得,递归出口往往是边界的时候
不断递归:每递归一次,下一次需要递归就会逐渐靠近这个递归出口
同时递归的开始的时候我们要把要递归的当成我们已知的,进行操作,如递归求n的阶乘为例,我们就假设n-1的递归值是已知的。

备注:递推必须要有递推出口

⭐求前n个斐波那契数

🎈具体代码:

#include<stdio.h>

int fabo(int n)
{
if (n == 1 || n == 2)
{
return 1;
}
return fabo(n - 1) + fabo(n - 2);

}

int main()
{
//递归求斐波那契数列的前50项的和
int i = 0;
for (i = 1; i <51;i++)
{
printf("%d\t", fabo(i));
}
return 0;
}

⭐具体代码(答案😇)

🎈递归出口:当数组只有一个元素
不断递归:那么我们就可以反向的推出:应该从数组下标大的一端开始递归,且把任务一步一步向递归出口逼近,同时调用自身。
🎈往里套用就是:
关键:重复把求最大值这个过程重复再重复,知道找到递归出口

1.当数组只有一个元素的时候,这个数就是最大值
2.但是当n>1时,从数组下标大的一端开始自身调用**,将最后一个数和n-1个数中的最大值进行比较(假设我们已知)**
3.然后就是求n-1个数中的最大值,也就是重复了以上的步骤
4.知道我们到了递归出口,再归回去就可以了。

#include<stdio.h>
int find_max(int* a, int n)
{

if (n == 1)
{
return a[0];
}

return a[n - 1] > find_max(a, n - 1) ? a[n - 1] : find_max(a, n - 1);


}
int main()
{
//递归求n个数中的最大值
int a[5] = { 55,22,155,77,99 };
int ret=find_max(a, sizeof(a) / sizeof(a[0]));
printf("%d\n", ret);
return 0;
}

运行结果:

【递归】递归求n个数中的最大值_数组_05