递归实现斐波那契数列以及详细解析

什么是递归:函数内部调用函数自身。

什么是斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89......像这样的数列,第一个数加第二个数等于第三个数,第二个数加第三个数等于第四个数,以这样的规律递推。F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)(≥ 3,∈ N*)

现在我将用Python来写递归实现斐波那契数列。

def fibonacci(n):  # n表示计算斐波那契数列数列中的哪个数
    if n in [1, 2]:
        return 1
    return fibonacci(n-1) + fibonacci(n-2)

if __name__ == "__main__":
    fibonacci(5)

好了这样就实现了,就只用了这么点点的代码就完成了通过递归计算出斐波那契数列中处于任何位置的数。看似很简单,但是背后的运行其实是很繁琐的。接下来会慢慢揭晓。

我们先来看看执行所需时间:

我们计算斐波那契数列的第30位数:

def fibonacci(n):  # n(n>0)表示计算斐波那契数列数列中的哪个数
    if n in [1, 2]:
        return 1
    return fibonacci(n-1) + fibonacci(n-2)

if __name__ == "__main__":
    start_time = datetime.now()
    fib_num = fibonacci(30)
    end_time = datetime.now()
    print("------------------------------")
    print("当前数为:", fib_num)
    print("耗时:", (end_time-start_time).total_seconds())
    print("------------------------------")

运行结果为:

再计算第31位(将代码中的参数改为31):

再计算第32位(将代码中的参数改为32):

再计算第33位(将代码中的参数改为33):

再计算第34位(将代码中的参数改为34):

再计算第35位(将代码中的参数改为35):

再计算第36位(将代码中的参数改为36):

再来计算第40位看看,跳了4位(将代码中的参数改为40):

我们仔细观察这些计算耗时,我们发现,每计算多一位数,所耗时间急剧上升,几乎翻倍,这是为什么呢?其实是由于做了大量重复的计算。我们看图说话:

上图是使用递归计算斐波那契数列的第七个数,我们可以看到,f7=f6+f5,f6=f5+f4......这样依次传递,直到最后得出f1或者f2就开始返回(return,归),这样最终计算出f7,但是我们可以看到,有大量重复的计算过程,比如:进行了5次f1+f2,进行了3次f2+f3......这还只是计算第七个数,如果计算更大的数,计算量会成几何倍增加,我们接下来修改代码试试计算斐波那契数列的第30个数,看看计算次数统计:

from datetime import datetime

total_num = 0  # 统计一共进行了多少次递归
total_dict = {}  # 统计每个的计算次数

def fibonacci(n):  # n(n>0)表示计算斐波那契数列数列中的哪个数
    if n in [1, 2]:
        return 1
    global total_num
    total_num += 1
    if n not in total_dict:
        total_dict[n] = 1
    else:
        total_dict[n] += 1
    return fibonacci(n-1) + fibonacci(n-2)

if __name__ == "__main__":
    start_time = datetime.now()
    fib_num = fibonacci(30)
    end_time = datetime.now()
    print("------------------------------")
    print("当前数为:", fib_num)
    print("耗时:", (end_time-start_time).total_seconds())
    print("执行递归次数:", total_num)
    print("各个数的计算次数统计:", total_dict)
    print("------------------------------")

运行结果为:

我们可以看到,斐波那契数列的第30个数是832040,运行耗时为0.302508秒,一共进行了832039次递归,再来看看各个数的计算次数统计,字典的key表示计算的斐波那契数列中的第几个数,value表示计算了多少次,比如8:28657,8表示斐波那契数列的第8个数,28657表示斐波那契数列的第8个数一共计算了28657次,即进行了28657次f7+f6。由于计算次数大量重复,导致消耗时间成几何倍增长。

上面是斐波那契数列的第30个数,我们再来看看斐波那契数列的31个数的运行结果:

对比后看看,各项数据有很大的差距。因此,按照这样的递归计算斐波那契数列是十分耗时并且不稳定的。

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值