1.题目
求解Fibonacci数列的第n项。
0 1 1 2 3 5 8 13 ...
2.数据结构与算法
方案1.分治递归
方案2.记忆(memoization)
方案3.动态规划(dynamic programming):由自顶而下的递归,转为自底而上的迭代。
3.源代码
#include "stdafx.h"
#include <iostream>
using namespace std;
//递归
int fib(int n){
return (n>2) ? fib(n-1)+fib(n-2) : 1;
}
//记忆
int fib2(int n){
int fibs[999] = {1, 1};
for(int i=2; i<n; i++){
fibs[i] = fibs[i-1] + fibs[i-2];
}
return fibs[n-1];
}
//DP迭代
int fib3(int n){
int f = 0, g = 1;
while(--n){
g = g + f;
f = g - f;
}
return g;
}
int main()
{
//测试:fib的第10项. 简易输入不要超过40,如果超过40,递归方式实现的fib(n)计算时间会开始显著延长。
int n = 10;
cout<<"递归实现:fib("<<n<<")="<<fib(n)<<endl;
cout<<"记忆实现:fib("<<n<<")="<<fib(n)<<endl;
cout<<"DP迭代实现:fib("<<n<<")="<<fib(n)<<endl;
//防止窗口关闭
cin.get();
}
4.时间复杂度
(一).递归实现
递
推
方
程
:
T
(
n
)
=
T
(
n
−
1
)
+
T
(
n
−
2
)
递推方程:T(n) = T(n-1) + T(n-2)
递推方程:T(n)=T(n−1)+T(n−2)
T
(
0
)
=
T
(
1
)
=
1
T(0) = T(1) = 1
T(0)=T(1)=1
计算:
令
S
(
n
)
=
[
T
(
n
)
+
1
]
/
2
,
令S(n)=[T(n)+1] / 2,
令S(n)=[T(n)+1]/2,
则
S
(
0
)
=
1
=
f
i
b
(
1
)
,
S
(
1
)
=
1
=
f
i
b
(
2
)
则S(0)=1=fib(1),S(1)= 1 = fib(2)
则S(0)=1=fib(1),S(1)=1=fib(2)
不
难
得
出
:
S
(
n
)
=
f
i
b
(
n
+
1
)
不难得出:S(n) = fib(n+1)
不难得出:S(n)=fib(n+1)
所
以
T
(
n
)
=
2
∗
f
i
b
(
n
+
1
)
−
1
=
ο
(
f
i
b
(
n
+
1
)
)
=
ο
(
ϕ
n
)
=
ο
(
2
n
)
所以T(n) = 2 * fib(n+1) - 1 = \omicron(fib(n+1)) = \omicron(\phi^n) = \omicron(2^n)
所以T(n)=2∗fib(n+1)−1=ο(fib(n+1))=ο(ϕn)=ο(2n)
递归fibs的时间复杂度为: ο ( 2 n ) \omicron(2^n) ο(2n)
(二).记忆实现
时间复杂度为:
ο
(
n
)
\omicron(n)
ο(n)
空间复杂度为:
ο
(
n
)
\omicron(n)
ο(n)
(三).DP迭代实现
显然时间复杂度为:
ο
(
n
)
\omicron(n)
ο(n)
空间复杂度为:
ο
(
1
)
\omicron(1)
ο(1)
5.结论
递归方式编写代码虽然清晰、简单。但算法性能往往并不如迭代算法。
究其原因,递归算法往往产生大量重复的递归实例。
如有错误,请您批评指正。
参考书籍:清华大学《数据结构(C++语言版)》(第三版) 邓俊辉
1630

被折叠的 条评论
为什么被折叠?



