数据结构(1)—fibonacci数列的复杂度

来源:互联网 发布:ipad淘宝开店 编辑:程序博客网 时间:2024/06/05 07:27

开始第二遍复习数据结构,决定把一些有意思的题目做个简单的小结,第一个遇见的是这个经典的Fibonacci数列,题目要求是求这个数列的时间复杂度,对于这个数列,我也不作过多的介绍,下面是对数列的几种简单的实现

1.初始版

long fibonacci1(int n){    if(n==0)        return 0;    if(n==1)        return 1;    if(n>1){        return fibonacci1(n-1)+fibonacci1(n-2);    }}//递归

这种写法是每一个初学者第一次接触到递归时都会写的,这是最为简单的写法,但也是递归效率最低的写法,对于计算Fibonacci(3)来说,就需要计算2次Fibonacci(1),递归调用过多,时间复杂度T(n)>O(2^n),所以,我们在求一个较大的Fibonacci数的时候可以想办法使得算法不用重复计算低阶的Fibonacci数,这时候我们可以使用一个简单的数组来存放已经求出来的Fibonacci数,这样就可以得到2.0版本了

2.加强版

long fibonacci2(int n){    long temp[1000]={0};    if(n==0){        return 0;    }    if(n==1){        return 1;    }    if(n>1){       if(temp[n]!=0)        return i[n];       else {        temp[n]=fibonacci2(n-1)+fibonacci2(n-2);        return i[n];       }    }}//递归2.0

这个里面我们使用temp数组对每一个递归求的数字进行存放,减少了递归时候的计算,这个时候的时间复杂度降到了O(n),但是,对于一个大的Fibonacci数,这个递归势必会引起栈的溢出,所以我们还可以尝试一下使用非递归从小到大的计算Fibonacci数列

3.非递归版

long fibonacci3(int n){    long temp[1000]={0};    if(n>0)        temp[1]=1;    int m;    for(m=2;m<n;m++){        temp[m]=temp[m-1]+temp[m-2];    }    long result = temp[n];    return result;}//非递归

因为是使用C语言进行编译而GCC不允许使用for(int ; ;)的语法,所以代码看起来有点奇怪,这个是非递归版本,每一个temp[i]存放的是Fibonacci(i)的值,时间复杂度也是O(n);

4.非递归加强版,这个是我在网上查资料看到的一种方法

Fibonacci数列可以改为矩阵乘法的形式,这样我们很容易求得它的通项公式,这样一来,这个问题就转而成为了一个求矩阵乘法的问题了。具体的过程可以参考其他博客。