斐波那契数列计算时间复杂度之彻底分析

#include<stdio.h>

#include<time.h>

递归法:

优点:形式简洁,便于人理解

缺点:虽说递归法以空间换时间,但一旦n变大,它的速度的确比非递归法慢得多,例如对n=40,测试递归法所用时间为8~9s;而非递归法只需要远不到1s。

原因是,递归过程中,系统建立堆栈来保存上一层状态信息, 和退栈获取还原系统状态都要有开销的.系统做的事情不少, 所以效率要低.

例如,f(5)的话,实际上会调用这个函数15次,有15个临时栈区,试想f(100)有多吓人。。。一般来说到f(40)以后,普通计算机基本上就不可能计算出来了

long Fib1(long n){

if(n<=1)

return n;

else

return Fib1(n-1)+Fib1(n-2);

}

非递归法:

总体来说,适合当n很大的情况

long Fib2(long n){

int f1 =    0;

int f2 =    1;

int f3;

int i;

for(i=2;i<=n;i++){

f3 =    f2 + f1;

f1 =    f2;

f2 =    f3;

}

return f3;

}

int main(){

clock_t start, finish;

double duration;

long b;

long a[40] =    {0,1};

start =    clock();

b =    Fib1(40);//耗时:7.889s

//  b =    Fib2(40);//耗时:0.175s

printf("%ld ",b);

finish =    clock();

duration = (double)(finish - start) / CLOCKS_PER_SEC;

printf("%f\n",duration);

return 0;

}

以前看数据结构与算法分析(C语言描述),作者在讲述算法分析时提到递归计算斐波那契数列,

Fib(int N)

{

if(N <= 1)

return 1;

else

return Fib(N - 1) + Fib(N-2);

}

时间复杂度T(N) = T(N-1) + T(N-2);

作者说归纳法易证得T(N) >= Fib(N);而Fib(N) < (5/3)^(N);类似计算可正得Fib(N)>= (3/2)^(N)

这个地方作者处理得有些不太彻底,不是吗?翻来覆去没把Fib(N)准确求出,今天我翻看另一本资料,

更模糊了,它求得2^(N/2) < T(N) < 2^(N)就完事了。

不过今天我开窍了,T(N) = T(N-1) + T(N-2);这是什么?也许你会说这是一个递推式,但它的学名是

二阶齐次差分方程,我今天猛然看出这一点:)!

什么是差分方程?

以下资料全部来自Introduction to Numerical Analysis,second Edition Translate by

Bartels,W.Gautsch and C.Witigall,Springer-Verlag,世界图书出版公司,(英文版)

这是我大三所用的数值分析教材,目前国内好像还没中文版。

书上464页说道:

By a linear homogeneous difference equation of order r one means an equation of the form

u(j+r) + a(r-1)u(j+4-1) + .... + a(0)u(j) =0;  j=0,1,2...  (7.2.9.1)

上面那些括号里的数一般是下标,我不好打出来,用括号代替了。

反正就是说齐次差分方程就是那个式子的形式了。

接着466页上讲到

Theorem. let the polynomial

Ψ(u) = u^r + a(r-1)u^(r-1) + ... + a(0)

have the k distinct zeros λ(i) ,i = 1,2,...,k

with multiplicities σ(i),i = 1,2,...,k

and let a(0) != 0,then for arbitray polynomials p(i)(t) with deg p(i) < σ(i),i = 1...k;

the sequence

u(j) = p(1)(j)λ(1)^(j) + p(2)(j)λ(2)^(j) +...+ p(k)(j)λ(k)^(j)

is a solution of the difference eqution (7.2.9.1).Conversely,every solution of

(7.2.9.1)can be uniquely represented in the form(7.2.9.9).

这段话又是什么意思呢?一句话:这是个牛逼的定理它导出了齐次差分方程的解并且说明了齐次差分方程

的所有解的形式。书上证明不是太短。

接下来举例说明。就拿斐波那契数列来说。

书上561页提了个问题,问题我就不打了,它问:

u(j+2) = u(j+1) + u(j)的通项公式是什么?然后它说u(0) = 0,u(1) = 1 即可得Fibonacci sequence

就是说这个式子从u(0) = 0,u(1) = 1递推即可得斐波那契数列。从其他初始状态的话可得其他数列。

开始解决问题。

按照那个牛逼定理,先解方程x^2 - x - 1 = 0;

这个不难,x1= (1+5^(1/2))/2,x2 = (1-5^(1/2))/2;

然后套公式u(j) = c1 * x1^(j) + c2 * x2^(j);

c1,c2为待定常数,利用u(0) = 0,u(1) = 1,得出c1 = 1/(5^(1/2));c2 = -c1;

这样斐波那契数列的通项就出来了,递归计算斐波那契数列时间复杂度问题也就迎刃而解了。

时间: 2024-10-20 15:50:08

斐波那契数列计算时间复杂度之彻底分析的相关文章

python 题目:斐波那契数列计算;题目:站队顺序输出;题目:合法括号组合的生成;题目:用户登录(三次机会)

斐波那契数列计算 B 描述 斐波那契数列如下: F(0) = 0, F(1) = 1 F(n) = F(n-1) + F(n-2) 编写一个计算斐波那契数列的函数,采用递归方式,输出不超过n的所有斐波那契数列元素 调用上述函数,完成如下功能: 用户输入一个整数n,输出所有不超过n的斐波那契数列元素.输出数列的元素和及平均数,输出按照顺序,用英文逗号和空格分割 此题目为自动评阅,请严格按照要求规范输入和输出. def jebona(n): if n==0: return 0 elif n == 1

斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)

对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - 1) + F(n - 2),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围内的非负整数,请设计一个高效算法,计算第n项F(n).第一个斐波拉契数为F(0) = 1. 给定一个非负整数,请返回斐波拉契数列的第n项,为了防止溢出,请将结果Mod 1000000007. 斐波拉契数列的计算是一个非常经典的问题,对于小规模的n,很容易用递归的方式来获取,对于稍微大一点的n,为

斐波拉契数列的代码书写和分析

什么是斐波拉契数列?   斐波拉契数列是指一个数列,其前两位等于1,第i位等于第i+1位于第i+2位相加.(1 1 2 3 5 8 13 ···) 斐波拉契数列实现代码的分析.   用户输入一个长度值,然后得到该长度的斐波拉契数列.要想实现这个功能,我们可以分成三个模块去书写代码:       1.获取用户输入的长度,保存到变量n中.       2.创建长度为n的数组,依次保存每一位数字.       3.遍历输出数组内容.   这样的话,我们只需要实现每个模块的功能,整个代码就能编写完成.

PHP_I love U之(2)php衣食父母: Java与PHP效率比拼之一:斐波那契数列

PHP_I love U之(1)php衣食父母: Java与PHP效率比拼之一: 斐波那契数列 Fibonacci 解释见:http://zh.wikipedia.org/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97 ( 应该是1 , 维基的公式错了!?!) (n≧2) 这次先写 Java的代码: class fb { static int f1b (int x) { if ((0==x)||(1==x) ) {  ret

斐波那契数列和反向计算问题

反向计算:编写一个函数将一个整型转换为二进制形式 反向计算问题,递归比循环更简单 分析:需要理解,奇数的二进制最后一位是1,偶数的二进制最后一位一定是0,联想记忆,这个和整型的奇偶性是一致的,1本身就是奇数,0本身是偶数. 十进制整数转换为二进制整数采用"除2取余,逆序排列"法. 具体做法是:用2整除十进制整数,可以得到一个商和余数,再用2去除商,又会得到一个商和余数,如此进行,直到商为0时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列

斐波那契数列两种时间复杂度

契数列 概述: 斐波那契数列,又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.--在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)在现代物理.准晶体结构.化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963起出版了以<斐波纳契数列季刊>为名的一份数学杂志,用于专门刊载这方面的研究成果. 求解: 求解斐波那契数列的F(n)有两种常用算法:递归算法和非递归算法.试分

斐波那契数列的三种时间复杂度

/*前边两个为一种做法*/ /*后边有另外的做法(差分方程以及利用矩阵去做)*/ //***************************************************//***************************************************//*************************************************** 第一种做法 这是2018王道数据结构考研复习指导的第一章思维拓展的题目. 关于斐波那契数列的简介:

Python计算斐波那契数列

利用Python计算第一个达到一百万位数的斐波那契数列各位数之和 结果为4501552 以下是我用到的代码,不是中间需要一些人工操作来加快收敛性,有兴趣读者可以写代码加快收敛 首先执行这个,可以大致确定一百万个数所在斐波那契序列的位置 i=1 j=1 k=i+j count=3 while count<4850000: i=j j=k k=i+j count+=1 result=str(k) print('k长度') k_len=len(result) print(k_len) sum=0 fo

ACdreamOJ 1116 斐波那契数列+hash计算后缀

http://acdream.info/problem?pid=1116 Problem Description give you a string, please output the result of the following function mod 1000000007 n is the length of the string f() is the function of fibonacci, f(0) = 0, f(1) = 1... a[i] is the total numb