大家一起学习,如果大家有什么意见或者建议可以与博主一起分享!
首先先让我们明白一个概念,什么叫递归调用,简单的说——直接或间接调用自身的算法称为递归调用。一个函数能够不断的重复调用自己,来达到计算的目的。递归函数代码精炼,却有着很大的作用,适合作用于复杂、大量的计算,而且对于计算机来说递归调用非常节省计算机运行的成本,提高计算机的运行效率。
有人可能会提问,这样无限的重复调用自己的函数不就成了无限死循环了吗,我们如何走出这个循环呢?这就引出了一个非常重要的概念:在递归调用中都必须有一个非递归定义的初始值用来走出这个循环,否则,递归函数就无法计算。
举个例子,假设要计算n!
我们都知道一个数的阶乘,是从 1 * 2 * 3 * …… * (n-1)*n 那么其中什么是属于非递归定义的初始值呢?其实我们一眼就能看出来,无论你的n取何值,你的阶乘计算永远都要从1开始。因此,这个1就是属于非递归函数的初始值。
所以阶乘函数可以写成这样的形式
注:在这里不考虑0的情况,因为0!就是0,没有意义,当然同学们在看完这篇文章之后可以试着将一些特殊情况考虑进去来提高自己的编程能力和逻辑思维能力。
如果有同学对我之前的文字描述没有看懂那么我举一个实际例子。
假设我需要计算5!
5!表示1 * 2 * 3 * 4 * 5
函数最后一项是乘5,因此之前的和可以表示为4!,即5*4!。那么现在我们需要知道4!怎么计算,于是我们调用我们定义好的阶乘函数。
4!表示1 * 2 * 3 * 4
函数最后一项是乘4,因此之前的可以表示为3!,即4*3!。那么现在我们需要知道3!怎么计算,于是我们继续调用我们定义好的阶乘函数。
3!表示1 * 2 * 3
因此之前的和应该表示为2!,即3*2!。现在我们需要知道2!
2!表示1*2
因此之前的和应该表示为1!,即2*1!。现在我们需要知道1!
1!就是表示1,在函数中1我们已经单独定义好了。
递归函数就是像这样不断的重复调用自己的函数,直到找到我们一开始定义的一个非递归的初始值。
因此整个递归函数的框架就变的清晰了起来
int DiGui(int n)
{
if( n == 1 ) //非递归的初始值,也是我们跳出函数自我调用的关键
return 1; //返回值,表示函数调用结束
else
return n*DiGui(n-1);
}
return n*DiGui(n-1)
有很多人这一步没有看懂,我来单独解释一下,首先我们定义了一个函数DiGui,我们给它附上的参数是n,n就用来表示这个递归函数表示的阶乘数。在这个函数中,当我们的n值为1的时候,即处于一个固定的初始值时就结束这个递归函数的自我调用,这一点在上面已经介绍过了。
那么在n为其他数的时候函数该如何调用自己呢?于是就有了这么一个 if else 语句,当n为5的时候,5的阶乘可以看做5 * 4 的阶乘,这个时候4的阶乘可以用我们已经定义的函数DiGui来表示,而4的阶乘可以看做4*3的阶乘,而3的阶乘也可以用我们已经定义的函数DiGui来表示,以此类推。
所以我们在else里面返回的时候不是某一个数值,而是返回我们函数本身,要注意的是DiGui的参数需要减1。直到DiGui(1)的时候,由于我们已经定义了一个初始值,所以就可以停止函数的调用,得到我们所需的结果。
新手同学可以做一道题练习一下,求n!的值,n需要自己输入。
下面我贴出我的C语言版的代码,同学们写好之后可以比较一下。
#include<stdio.h>
int DiGui(int n)
{
if( n == 1 )
return 1;
else
return n*DiGui(n-1);
}
int main()
{
int n;
printf("please input n: ");
scanf("%d",&n);
printf("Result: %d\n",DiGui(n));
return 0;
}