递归算法的实际运算情况以及其弊端
为了方便说明递归算法的实质运算过程,我们来看一个例子:
例:已知有五个人,第一个人年龄为10岁,第二个人比第一个人年龄大两岁,第三个人比第二个人大两岁,第四个人比第三个人大两岁,第五个人比第四个人大两岁.求第五个人的年龄?
分析:此处我们使用递归算法的思想来进行分析,由题可知:
//Age(5):第5个人的年龄
//Age(4):第4个人的年龄
//Age(3):第3个人的年龄
//Age(2):第2个人的年龄
//Age(1):第1个人的年龄
//Age(n):第n个人的年龄
//Age(n-1):第n-1个人的年龄
那么相应的代码如下:
int Age(int n)
{
int tmp;
if(n == 1)
{
return 10;
}
else
{
tmp = Age(n-1) + 2;
return tmp;
}
}
int main()
{
printf("%d\n",Age(5));
return 0;
}
运行结果如图所示
接下来我们分析递归算法的运算过程是怎样的,如下图所示.:
分析:
程序运行后,首先会计算Age(5)的结果,但是要想知道Age(5)的结果必须要知道Age(4)的结果, 要想知道Age(4)的结果必须要知道Age(3)的结果…以此类推我们最终轮到了Age(1)的头上,然而Age(1)是我们已知的,其值为10.那么显而易见我们在程序运行过程中需要一个地方去存贮我们需要完成计算的Age(5)、Age(4)、Age(3)、Age(2)、Age(1),那么我们要知道递归算法的临时变量是保存在栈这个地方的,我们的临时变量或未运行完的函数保存在栈的栈帧中,如紫色图所示,Age(5)、Age(4)、Age(3)、Age(2)、Age(1)每个函数都保存在一个栈帧中。当函数从n=5一直调用到n=1时,不断地会往栈中保存未完成的函数,并且最先进行的函数保存在最底层,这也是栈的特点,先进后出的特点。那么当程序运行到n=1时,此时Age(1)的值我们是知道的,那么就开始出栈,以Age(1)、Age(2)、Age(3)、Age(4)、Age(5)的次序依次出栈,并且最终将结果返回给主函数。
那么递归算法的弊端是什么呢?为什么不提倡使用递归算法呢?
原因在于栈这个地方是非常小的,栈的内存大小只有1M左右,所以若是程序调用上万次时,那么栈中放不下就会导致程序崩溃,所以一般情况下不提倡使用递归算法!