标签:color 递归 初学 for 计算 介绍 pre 允许 不用
开始第二遍复习数据结构,决定把一些有意思的题目做个简单的小结,第一个遇见的是这个经典的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数列可以改为矩阵乘法的形式,这样我们很容易求得它的通项公式,这样一来,这个问题就转而成为了一个求矩阵乘法的问题了。具体的过程可以参考其他博客。
标签:color 递归 初学 for 计算 介绍 pre 允许 不用
原文地址:http://www.cnblogs.com/c-xiao/p/7407203.html