Fibonacci数列 递归与DP迭代

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(n1)+T(n2)
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) (n)=2fib(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++语言版)》(第三版) 邓俊辉

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值