菲波拉契数的时间-空间复杂度--递归树

这篇博客探讨了斐波拉契数列的Python实现,包括递归和迭代两种方法。递归方法的时间复杂度为2^n,空间复杂度为O(n),而迭代法的时间复杂度降低到O(n),空间复杂度优化为O(1)。文章通过实例展示了如何计算这两种方法的复杂度,并对比了它们在实际运行时间上的差异。最后,提到了可以通过公式进一步优化时间复杂度至O(1)。
摘要由CSDN通过智能技术生成

1.python的简单实现 

菲波拉契数的python代码的简单实现:1 ,1,2,3,5,8,13,21,34... 

可以看出,后面的数是前两个数的和。

# 菲波拉契数

# 委递归计算
# 时间复杂度为:2^n
# n从1开始
def fib(n):
    if n < 3:
        return 1
    return fib(n-2) + fib(n-1)

print(fib(40))

菲波拉契数的时间复杂度的计算

我们可以看出,菲波拉契数的时间复杂度可以用下面的公式表示: 

 T(n) = T(n-1) + T(n+1)

          我们可以先简单的写一个求第10个的数的递归过程:

我们先将其画到递归结束的程度,而我们每层的每一个f(n)都有一个加法的操作,所以每层的f(n)都需要一个时间复杂度(这样写好理解一些),所以:

所以我们求n个数时:O(2^{n-1}),所以最终的复杂度是O(2^{n}).

2.空间复杂度计算(递归的空间复杂度计算)

         所谓的空间复杂度,就是用于保存变量的空间。如:

def add():
    a,b = 0,0
    for i in range(100):
        for j in range(100):
            a += i
            b += j
            s = a + b
    return s

      上面的代码的空间复杂度为O(1),运行后,一共需要4个单位的空间复杂度 ,因为一共保存了4个变量。

       上面的非常好看出来,那么递归代码的空间复杂度怎么计算呢?

       比如:上面的菲波拉契数的空间复杂度计算?

       先说说上下文切换吧,什么叫上下文的切换呢?在操作系统里面,在函数f1中,调用了f2,在f2中我们调用了f3,这种函数与函数的每次的调用关系,我们称之为上下文切换。而每一次的上下文切换,我们都需要有一个内存空间的使用,内存空间的使用有两种方法:

  • 通过变量的方式使用
  • 上下文切换的操作,也会占内存空间

上面两种的方法占用的内存空间是不一样的。 好了,我们回到空间复杂度的计算上:

       其实递归的内存占用可以看作一个栈,进行一次上下文切换就进一次占,而到达递归的结束条件呢,则开始依次出栈,而这个时候,也是这个递归函数此次运行时所占的多少单位的空间复杂度了。

就好像我们计算f(8)=f(6)+f(7),这个时候栈中就有了3个单位的空间复杂度了,分别是f(8),f(6),f(7)。。。

依次写下去,你会发现菲波拉契数的空间复杂度其实是O(n)。

注:记得出栈,出栈后,空间自然释放,不是一共使用了多少空间,而是最大使用了多少空间。

 

下面我们对菲波拉契数的代码进行改进:

# 菲波拉契数

import time

# 委递归计算
# 时间复杂度为:2^n
def fib_1(n):
    if n < 3:
        return 1
    return fib_1(n-2) + fib_1(n-1)

# 迭代法
def fib_2(n):
    f1 = 1
    f2 = 1
    for i in range(3, n+1):
        f3 = f1+f2
        f1, f2 = f2, f3
    return f3

statr_1 = time.time()
print(fib_1(40))
end_1 = time.time()
statr_2 = time.time()
print(fib_2(40))
end_2 = time.time()
print(f"fib_1: {end_1-statr_1}\nfib_2: {end_2-statr_2}")

通过对运行时间的比较,很容易看出:在30左右的时候还没有太大的区别,但n越大,fib_2的速度是更快的。

优化后:

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

可以说是有了本质的一个区别。 

 

还可以套公式:使得时间复杂度为O(1)....

 

本文是学习时间-空间复杂度的笔记,如有错误,望指教。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值