斐波那契数列介绍
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列: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起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。
递归解法
long long fibonacci_recursion(unsigned int n)
{
if (n <= 0)
return 0;
if (1 == n)
return 1;
return fibonacci_recursion(n-1) + fibonacci_recursion(n-2);
}
递归解法虽然写起来很简便,但是当n很大时,运算很慢,事实上,用递归方法计算的时间复杂度是以n的指数的方式递增的。
我们以求解f(10)作为例子来分析递归求解的过程。要求得f(10),需要求得f(9)和f(8)。同样,要求得f(9),要先求得f(8)和f(7)……我们用树形结构来表示这种依赖关系
f(10)
/ \
f(9) f(8)
/ \ / \
f(8) f(7) f(7) f(6)
/ \ / \
f(7) f(6) f(6) f(5)
我们不难发现在这棵树中有很多结点会重复的,而且重复的结点数会随着n的增大而急剧增加。这意味这计算量会随着n的增大而急剧增大。事实上,用递归方法计算的时间复杂度是以n的指数的方式递增的。大家可以求Fibonacci的第100项试试,感受一下这样递归会慢到什么程度。
迭代解法
long long fibonacci_iteration(unsigned int n)
{
long long f0 = 0;
long long f1 = 1;
long long f2 = 0;
unsigned int i = 0;
if (n <= 0)
return f0;
if (1 == n)
return f1;
for(i=2; i<=n; ++i){
f2 = f1 + f0;
f0 = f1;
f1 = f2;
}
return f2;
}
这里的迭代方法消除了递归中的重复的计算,迭代的时间复杂度是O(N),最实用。
时间复杂度为O(logN)的解法
懒得写,给个链接吧,链接如下:
http://blog.sina.com.cn/s/blog_6ab0b9a80101axdn.html