从两种斐波那契数的实现认识递归算法

目录

 

一、斐波那契数列定义

二、两种递归实现方式及分析

1、方式一:使用数学公式直接实现(二分递归)第n个斐波那契数

2、方式二:使用线性递归计算第n个斐波那契数(推荐方式)

三、对递归的认识

四、其他概念


一、斐波那契数列定义

关于斐波那契数列的定义引用百度百科:


斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……这个数列从第3项开始,每一项都等于前两项之和。在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(≥ 2,∈ N*)


二、两种递归实现方式及分析

根据斐波那契数列数学定义:

F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(≥ 2,∈ N*)

如下两种使用递归计算斐波那契数列的方法(python3):

1、方式一:使用数学公式直接实现(二分递归)第n个斐波那契数

def fibonacci_1(n):
    if n<=1:
        return n
    else:
        return fibonacci_1(n-2)+fibonacci_1(n-1)

这种方式中,是基于数学定义直接实现,也是很简便的实现方法,但是,需要关注的问题是,这种方式也会直接导致方法的执行效率会非常低,会随着n越大,其效率也更低。计算第n个斐波那契数需要对该方法进行指数级别的调用。假设用Cn表示第n个斐波那契数需要调用fibonacci_1(n)的次数,有如下:

第n个斐波那契数调用方法次数
n=0C0=1
n=1C1=1
n=2

C2=C0+C1+1=3

n=3C3=C1+C2+1=5
n=4C4=C2+C3+1=9
n=5C5=C3+C4+1=15
n=6C6=C4+C5+1=25
n=7C7=C5+C6+1=41
n=8C8=C6+C7+1=67
n=9C9=C7+C8+1=109

如果一直按照这个方式进行下去,我们可以从上表中看出,n越大调用次数也越多,使得调用的总次数时n的指数级。

使用如下程序段计算50次(windows10 CPU 1C):

if __name__ == "__main__":
    t1 = time.clock()
    for i in range(50):
        t11 = time.clock()
        print("n={},fibonacci={}".format(i,fibonacci_1(i)))
        t12 = time.clock()
        print("cost time:{}".format(t12-t11))
    t2 = time.clock()
    print("sum time:{}".format(t2-t1))

截取了部分结果:n=31时,花费时间0.4s,但是当n=41时,需要时间52s,这样看来n越大,效率是很低的。

n=31,fibonacci=1346269
cost time:0.43121010000000004
n=32,fibonacci=2178309
cost time:0.714747
n=33,fibonacci=3524578
cost time:1.3300094999999998
n=34,fibonacci=5702887
cost time:1.7607852999999998
n=35,fibonacci=9227465
cost time:2.8848124000000004
n=36,fibonacci=14930352
cost time:4.900053
n=37,fibonacci=24157817
cost time:7.670326699999999
n=38,fibonacci=39088169
cost time:13.099861399999998
n=39,fibonacci=63245986
cost time:20.710187599999998
n=40,fibonacci=102334155
cost time:32.3978941
n=41,fibonacci=165580141
cost time:52.244939900000006

 

2、方式二:使用线性递归计算第n个斐波那契数(推荐方式

def fibonacci_2(n):
    if n<=1:
        return (n,0)
    else:
        (a,b) = fibonacci_2(n-1)
        return (a+b,a)

方式二每次只调用fibonacci_2方法一次,该方法每次返回一对连续的斐波拉契数列,而不是返回一个斐波那契数,在O(n)时间内完成整体计算。

同样计算50次,截取了部分结果如下:每次花费的时间都非常小,总共的时间也在1秒以内。

n=32,cost time:7.000000000000062e-06
n=33,cost time:7.299999999994811e-06
n=34,cost time:7.699999999999374e-06
n=35,cost time:7.900000000005125e-06
n=36,cost time:8.100000000003937e-06
n=37,cost time:8.099999999996998e-06
n=38,cost time:8.399999999998686e-06
n=39,cost time:8.500000000001562e-06
n=40,cost time:8.79999999999631e-06
n=41,cost time:8.899999999999186e-06
n=42,cost time:9.200000000000874e-06
n=43,cost time:9.500000000002562e-06
n=44,cost time:9.699999999994435e-06
n=45,cost time:9.80000000000425e-06
n=46,cost time:1.0200000000001874e-05
n=47,cost time:1.0599999999999499e-05
n=48,cost time:1.0700000000002374e-05
n=49,cost time:1.0999999999997123e-05

三、对递归的认识

     使用递归时,就效率而言,效率低的递归和效率高的递归,就如同白天和黑夜,差别悬殊。对于一个实际问题,对于递归算法的设计显得尤为重要。另一个需要注意的问题是在递归误用,避免出现无限递归,会很快耗尽计算机资源,不仅仅是CPU的使用,也会因连续不断的调用创建需要的内存资源。

四、其他概念

1、线性递归

每个调用中至多执行调用一个新的递归调用

2、二路递归

一个递归函数执行调用两个递归函数时,称为二路递归

3、多重递归

一个递归函数执行调用三个或三个以上递归函数时,称为多重递归

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C-Jonn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值