递归:函数自己不断调用自己(递),直到调用到唯一已知对象(终止条件)后,开始层层返回上一步(归)的一个完整过程。
递归作为一种算法在编程中广泛应用,它通常把一个大型复杂的问题层层转化为一个个与原问题相似、规模较小的问题来求解。
递归需要边界条件(终止条件),当边界条件不满足时,递归前进;当边界条件满足时,递归返回。如果没有边界条件,只递无归的话,会造成栈溢出,导致程序崩溃。
递归的优点:在某些特定的问题上,能通过简单的递归关系得到解决。递归算法只需少量程序就可描述出解题过程所需的多次重复计算,使得程序更加简洁,也更能体现问题的规律性。
递归的缺点:递归算法解题相对常用的算法如普通循环等,运行效率较低。在递归调用的过程当中,系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等问题。所以应尽量避免使用递归。
该例子可以替代递归的方法:1.利用等差数列求和公式,S(n)=n(a1+an)/2 a1、an分别代表数列首项、尾项。
2.使用循环,如for(i=1;i<=n;i++) S=S+i;
ps:(个人理解递归)递归相当于俄罗斯套娃,比如当你想知道最外面一个(1)娃娃的尺寸时,但只告诉你这个尺寸是里面一个(2)娃娃的尺寸加上某个值,然后里面的(2)娃娃也是再里面一个(3)娃娃的尺寸加某个值,以此类推。假设套娃是无穷的,这时就需要一个边界条件来停止继续拆下去的行为。比如我拆到第(20)个娃娃时,预估这个娃娃尺寸是3(终止条件),然后把(20)娃娃的尺寸--"3"往回代入,最终得到(1)娃娃的尺寸。所以递归关系需要终止条件来进行(归)过程,且需注意递归深度(次数)。
//递归的演示
自定义sum函数实现自然数求和
#include<stdio.h>
int sum(int n); //函数声明
int main()
{
int n, s = 0;
printf("计算n以内的自然数列之和,请输入n的值:");
scanf_s("%d", &n);
s = sum(n); //函数调用
printf("该自然数列之和为:%d", s);
return 0;
}
int sum(int n) //函数定义
{
if (n == 1)
return 1;
else
return (sum(n - 1) + n);
}
递归:sum(n)--> sum(n - 1) + n--> sum(n - 1) + n--> sum(n - 1) + n--> …-->遇到终止条件
假设n=4,
递过程:sum(4)--> sum(4 - 1) + 4--> sum(3 - 1) + 3--> sum(2 - 1) + 2 -->终止条件(n=1,即sum(1)=1)
归过程:sum(4) <--[sum(3)=6]+4=10 <--[sum(2)=3]+3=6 <--[sum(1)=1]+2=3 <--sum(1)=1
这里的终止条件是自然数列的第一个数1,在if 语句上,n=1时,返回1,所以归过程从1值开始层层往回代入。