斐波那契数列几种算法分析.doc

  1. 1、本文档共10页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
斐波那契数列几种算法分析

斐波那契数列算法分析 背景: 假定你有一雄一雌一对刚出生的兔子,它们在长到一个月大小时开始交配,在第二月结束时,雌兔子产下另一对兔子,过了一个月后它们也开始繁殖,如此这般持续下去。每只雌兔在开始繁殖时每月都产下一对兔子,假定没有兔子死亡,在一年后总共会有多少对兔子? 在一月底,最初的一对兔子交配,但是还只有1对兔子;在二月底,雌兔产下一对兔子,共有2对兔子;在三月底,最老的雌兔产下第二对兔子,共有3对兔子;在四月底,最老的雌兔产下第三对兔子,两个月前生的雌兔产下一对兔子,共有5对兔子;……如此这般计算下去,兔子对数分别是:1, 1, 2, 3, 5, 8, 13, 21, 34, 55,89, 144, ...看出规律了吗?从第3个数目开始,每个数目都是前面两个数目之和。这就是著名的斐波那契(Fibonacci)数列。 有趣问题: 1,有一段楼梯有10级台阶,规定每一步只能跨一级或两级,要登上第10级台阶有几种不同的走法? 答:这就是一个斐波那契数列:登上第一级台阶有一种登法;登上两级台阶,有两种登法;登上三级台阶,有三种登法;登上四级台阶,有五种方法……所以,1,2,3,5,8,13……登上十级,有89种。 2,数列中相邻两项的前项比后项的极限是多少,就是问,当n趋于无穷大时,F(n)/F(n+1)的极限是多少? 答:这个可由它的通项公式直接得到,极限是(-1+√5)/2,这个就是所谓的黄金分割点,也是代表大自然的和谐的一个数字。 数学表示: Fibonacci数列的数学表达式就是: F(n) = F(n-1) + F(n-2) F(1) = 1 F(2) = 1 递归程序1: Fibonacci数列可以用很直观的二叉递归程序来写,用C++语言的描述如下: long fib1(int n) { if (n = 2) { return 1; } else { return fib1(n-1) + fib1(n-2); } } 看上去程序的递归使用很恰当,可是在用VC2005的环境下测试n=37的时候用了大约3s,而n=45的时候基本下楼打完饭也看不到结果……显然这种递归的效率太低了!! 递归效率分析: 例如,用下面一个测试函数: long fib1(int n, int* arr) { arr[n]++; if (n = 2) { return 1; } else { return fib1(n-1, arr) + fib1(n-2, arr); } } 这时,可以得到每个fib(i)被计算的次数: fib(10) = 1 fib(9) = 1 fib(8) = 2 fib(7) = 3 fib(6) = 5 fib(5) = 8 fib(4) = 13 fib(3) = 21 fib(2) = 34 fib(1) = 55 fib(0) = 34 可见,计算次数呈反向的Fibonacci数列,这显然造成了大量重复计算。 我们令T(N)为函数fib(n)的运行时间,当N=2的时候我们分析可知: T(N) = T(N-1) + T(N-2) + 2 而fib(n) = fib(n-1) + fib(n-2),所以有T(N) = fib(n),归纳法证明可得: fib(N) (5/3)^N 当N4时,fib(N)= (3/2)^N 标准写法:、 显然这个O((3/2)^N) 是以指数增长的算法,基本上是最坏的情况。 其实,这违反了递归的一个规则:合成效益法则。 合成效益法则(Compound interest rule):在求解一个问题的同一实例的时候,切勿在不同的递归调用中做重复性的工作。 所以在上面的代码中调用fib(N-1)的时候实际上同时计算了fib(N-2)。这种小的重复计算在递归过程中就会产生巨大的运行时间。 递归程序2: 用一叉递归程序就可以得到近似线性的效率,用C++语言的描述如下: long fib(int n, long a, long b, int count) { if (count == n) return b; return fib(n, b, a+b, ++count); } long fib2(int n) { return fib(n, 0, 1, 1); } 这种方法虽然是递归了,但是并不直观,而且效率上相比下面的迭代循环并没有优势。 迭代解法: Fibonacci数列用迭代程序来写也很容易,用C++语言的描述如下: //也可以用数组将每次计算的f(n)存储下来,用来下次计算用(空间换时间) long fib3 (int n) { long x = 0, y = 1; for (int j = 1; j n; j++) {

文档评论(0)

pangzilva + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档