一、什么是递归
递归就是函数调用自己,类似于循环,使用递归一定要有结束递归的语句,这个语句一般是if条件语句。
二、递归与循环在一定程度上能够等价
除了在一些算法中使用递归,其他的我们都用循环来解决。因为递归会拖累程序的速度,并且会占据很大内存。
三、尾递归
尾递归是最简单的一种递归形式,函数调用自己的这一部分正好紧挨着return;
四、通过递归来求阶乘运算
//通过递归来求取阶乘运算
#include <stdio.h>
long rfact(int);
int main(void)
{
int num;
printf("This program calculates factorials\n");
printf("Enter a value in the range 0-12 (q to quit)\n");
while (scanf("%d",&num)==1)//1
{
if (num<0)//2
{
printf("No negative numbers,please\n");
}
else if (num>12)//3
{
printf("Keep input under 13\n");
}
else//4
{
printf("recursion %d factorials=%ld\n",num,rfact(num));
}
}
return 0;
}
//下面来定义这rfact()这个函数
long rfact(int n)//5
{
long ans;//6
if (n>1)//7
{
ans=n*rfact(n-1);//8
}
else//9
{
ans=1;
}
return ans;//10
}
下面来详细介绍这个尾递归程序:
1.
输入一个整数,如果是整数的话则进入循环,如果不是整数,则不进入循环,结束程序。
2.
循环头判断输入的是不是整数,if判断的是,输入的是不是大于0的数,如果num<0,则在这个if else组合中,只执行if语句。
3.
else if判断的是输入的整数是不是大于12,如果大于12,则只执行else if这个语句。
4.
如果输入的数据符合条件,将进入else语句,else语句将打印一句话,里面含有两个值,一个是num的值,也就是所要求的阶乘,
一个是rfact(num)的值,也就是rfact()函数的返回值,这个代表阶乘大小。
5.
定义这个求阶乘的函数
6.
由于需要一个long型的返回值,因此我们先定义一个long型变量
7、8、9、10
求阶乘的思想:n!=n(n-1)!=n(n-1)(n-2)!......
由于我想定义的阶乘函数是:rfact(),因此上面的式子又可以这样表达:
rfact(n)=n rfact(n-1)=n (n-1) rfact(n-2)......
因此考虑到我们可以使用递归求取。(在每一个求阶乘的式子中都可以在调用一个求阶乘)
由于我们只用一重递归,又因为返回值就是阶乘的值,因此我们可以写出表达式:ans=n*rfact(n-1)
如何确定终止条件,对于递归问题,我们需要使用反向思维来确定。
阶乘到最后应该是2*1,也相当于2成rfact(1),1的阶乘就是1,所以我们可以让他在这停止,也就可以把n>1当成终止条件。
假设输入的是4,我们来分析一下这个程序到底怎么运行:
1.首先,main()函数调用这个阶乘函数,4>1,因此进入if语句ans = 4 x rfact(3),同时进入第一级递归。
2.第一级递归,n=3,由于n>1,(注意,这个n相当于上一级的n-1,因此可以发现,每一级递归虽然变量名字一样,但是他们所代表的是不同的变量,因为储存的值不同),进入if语句 ans = 3 x rfact(2) ,同时进入第二级递归。
3.第二级递归,n=2,由于n>1,进入if语句 ans = 2 x rfact(1),同时进入第三级递归。
4.第三级递归,n=1,由于1=1,因此进入else语句,ans=1,接着执行下一条语句,也就是return ans;所以ans=1是rfact(1)的返回值,因此rfact(1)=1,由于不再进行递归,并且这一级执行完毕(return就代表结束这一级递归,返回到上一级递归处),返回上一级递归。
5.返回到第二级递归,在第二级中,程序运行到ans=2 x rfact(1),所以ans=2,接着执行下面语句,也就是return ans;所以这级递归执行完毕,继续返回到上一级,并且rfact(2)=2;
6.返回到第一级递归,在第一级中,程序运行到ans=3 x rfact(2),所以ans=6,接着执行return ans;所以这级递归执行完毕,继续返回上一级,并且rfact(3)=6;
7.返回到主函数中,在主函数中,程序运行到ans=4 x rfact(3),因此ans=24,接着执行return ans;因此rfact(4)=ans=24
*重点:
由上可知,程序是正着进入各级递归,倒着退出各级递归,并且倒出来的时候要把相应级的整个函数语句执行完毕才能往回倒。