斐波那契数列,递归与循环

斐波那契数列(Fibonacci sequence),又称黄金分割数列、兔子数列,是数学家列昂纳多·斐波那契于1202年提出的数列。
斐波那契数列为1、1、2、3、5、8、13、21、34……此数列从第3项开始,每一项都等于前两项之和,递推公式为F(n)=F(n-1)+F(n-2),n≥3,F(1)=1,F(2)=1。(老规矩,继续抄搜狗百科的一段介绍)
斐波那契数列通项的数学公式如下在这里插入图片描述
但是在编程程序中实现斐波那契数列通项的计算,只需要根据其规律,就很简单的实现了。最被人轻易的想到的实现方法一般有两种,循环和递归实现,循环实现如下

int fibo(const int n)
{
	assert(n >= 0);//参数断言
	int k1 = 1;
	int k2 = 1;
	int k3;
	if(n == 1 || n == 2)
		return k1;
	for(int i = 2;i < n;++ i)
	{
		k3 = k1 + k2;
		k1 = k2;
		k2 = k3;
	}
	return k3;
}

说一下,这里定义三个变量,第一项第二项,还有通过规律求和所得的第三项,判断语句判断需要求的项若是第一二项,直接返回值为1,若为大于第二项之后的项,则通过k1,k2,k3,三个标记来求得。k1,k2分别标记第一二项,然后第三项通过一二项求得,然后标记往后走,第三项别为第二项,第二项变为第一项,然后循环加一。就实现了通过循环求斐波那契数列项。
递归要比循环还要简单代码如下

int fibo(const int n)
{
	assert(n >= 0);
	if(n == 1 || n == 2)
		return 1;
	else
		return (fibo(n - 1)+fibo(n - 2));
}

直接若第一项或者第二项就返回1,之后项就通过求前两项之和,代码十分简单,但是有弊端,像汉诺塔一样,使用递归的方法,但是斐波那契数列并不适合用递归来实现,若是我们需要求的项是很大的项,例如这里测试的是第四十项,通过循环的话,结果是一瞬间得出的,而使用递归的话,需要等待大概七秒钟左右的时间,这只是第四十项,在效率方面就已经这么明显的体现出来,再大的项,使用递归,可能直接奔溃。这里附上两张图来说明一下。
在这里插入图片描述
在这里插入图片描述
这里以n为五为例,普通变量是保存在栈中的,若是函数不结束,就不会被释放,然而栈帧存储并不大,所以,n为5,进入到递归函数中,执行至else后语句,他会再次调用n=4,此时函数继续执行至else后的语句再调用n=3,并且之前的n=5和n=4的内存并不释放,一直调用至n=2与n=1(写到这里才注意到出栈图是有一点问题的,n=2的地方应该是执行完毕的,并非执行至else暂停),然后函数得到结果,返回给n=3,n=4,n=5,逐级返回,每有一个函数运行完毕,该函数的内存才会释放,所以递归函数再执行时,若是需要递归的次数太过多,会一直占用着栈帧无法释放,若需要的内存大过栈帧的大小,程序就会奔溃掉,所以这也是该程序使用递归实现不适合的原因。
相比较之下,循环就不同了,循环仅仅需要创建k1,k2,k3,三个标记变量,就可以实现,所以占用内存并不大,运行相对也会快很多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值