菲波那切数列和函数的递归调用(及部分例子)

本文以菲波那切数列为示例,详细讲解了递归调用的概念及其在代码实现中的应用。通过两种不同的递归方式展示了菲波那切数列的计算,同时指出了递归调用的效率问题和可能导致的栈溢出。递归调用虽然简化了代码,但其重复计算和栈空间消耗限制了在某些场景下的适用性。此外,还给出了阶乘和求和的递归实现示例,强调了递归在解决复杂问题时的层次转化思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       

以菲波那切数列为例:

菲波那切数列可以表示为:11235813。。。。。

写出菲波那切数列for循环的代码:

#include <stdio.h>

int Fibon(int n)

{

int f1 = 1;

int f2 = 1;

int fn;

if(n<3)

{

return 1;

}

for(int i=1;i<n;i++)

{

fn = f1 + f2;

f1 = f2;

f2 = fn;

}

return fn;

}

int main()

{

printf("%d\n",Fibon(1));

printf("%d\n",Fibon(2));

printf("%d\n",Fibon(3));

printf("%d\n",Fibon(4));

printf("%d\n",Fibon(5));

printf("%d\n",Fibon(6));

}

 

通过观察发现,菲波那切数列也可以表示为:f(n)=f(n-1)+f(n-2)

如果用上面的公式求出斐波那契数列,代码应为:

int Fibon(int n)

{

int tmp;

if(n==1||n==2)

{

return 1;

}

else

{   

/* error:return f(n)=f(n-1)+f(n-2); //注意此处不能用,因为f是未定义的标识符。*/

/*error: return  Fibon(n)=Fibon(n-1)+Fibon(n-2);//表达式必须是能修改的左值*/

return tmp=Fibon(n-1)+Fibon(n-2);//可以定义一个形参,来保存f(n)的值。

//也可以考虑不用形参的形式,如:

return Fibon(n-1)+Fibon(n-2);

}

}

int main()

{

printf("%d\n",Fibon(1));

printf("%d\n",Fibon(2));

printf("%d\n",Fibon(3));

printf("%d\n",Fibon(4));

printf("%d\n",Fibon(5));

printf("%d\n",Fibon(6));

}

 

例如方法二中的,在函数调用中,如果直接或者间接的调用函数本身,我们叫做递归调用。递归调用有时也被称为循环定义。

例如:在菲波那切数列的代码中,我们定义了int Fibon(int n),求出结果时,我们又用了 return Fibon(n-1)+Fibon(n-2)。这就是函数调用最明显的标志。但现实中并不推荐使用递归来实现菲波那切数列,这也是递归的缺点。

递归的缺点主要有以下几个方面:

1.递归由于是函数调用自身,而函数调用是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址以及临时变量,而往栈中压入数据和弹出数据都需要时间。->效率

2.递归中很多计算都是重复的,由于其本质是把一个问题分解成两个或者多个小问题,多个小问题存在相互重叠的部分,则存在重复计算,如fibonacci斐波那契数列的递归实现。->效率

3.调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出。->性能


类似的例子还有很多,例如:

n![n!=(n-1)!*n]:

int Num(int n)

{

if(n==0||n==1)//0的阶乘是1

{

return 1;

}

else 

{

return Num(n-1)*n;

}

}

int main()

{

printf("%d\n",Num(0));

printf("%d\n",Num(1));

printf("%d\n",Num(2));

printf("%d\n",Num(5));

}

 

 

求和[f(n)=f(n-1)+n]:

int sum(int n)

{

if(n==0)

{

return 0;

}

else

{

return sum(n-1)+n;

}

}

 

int main()

{

    printf("%d\n",sum(0));

printf("%d\n",sum(1));

printf("%d\n",sum(5));

printf("%d\n",sum(10));

}

 

 

从上面的代码,我们不难看出,递归通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描绘出解题过程所需要的多次重复计算,大大减少了程序的代码量。

递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件-----用来缩小规模还要有递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值