递归时间复杂度分析 —— 斐波那契数列

一、斐波那契数列

  • 所谓斐波那契数列,是指【当前项】的值等于【前两项】之和的数列:
i i i0123456789
f ( i ) f(i) f(i)11235813213455
  • 该数列有递推公式如下:

f ( n ) = { 1 ( n = 0 ) 1 ( n = 1 ) f ( n − 1 ) + f ( n − 2 ) ( n > 2 ) f(n) = \begin{cases} 1 & (n = 0) \\ 1 & (n = 1) \\ f(n-1) + f(n-2) & (n > 2) \end{cases} f(n)=11f(n1)+f(n2)(n=0)(n=1)(n>2)

二、递归求解斐波那契数列

  • C++ 代码实现如下:
int f(unsigned int n) {
	if(n <= 1) {
		return 1;
	}
	return f(n-1) + f(n-2);
}
  • 直接根据公式进行递归求解;

三、时间复杂度分析

  • 图解求解的过程如下:
n
n-1
n-2
n-2
n-3
n-3
n-4
n-3
n-4
n-4
n-5
n-4
n-5
n-5
n-6
  • 这是一棵二叉树,树的高度为 n,所以粗看深度优先搜索时访问的结点数为 2 n 2^n 2n,但是仔细看,最左边的结点的高度一定比右边结点的高度大,所以不是一棵严格的完全二叉树。为了探究它实际的时间复杂度,我们改下代码:
int f(unsigned int n) {
	++c[n];
	if(n <= 1) {
		return 1;
	}
	return f(n-1) + f(n-2);
}
  • 加了一句代码 ++c[n];,引入一个计数器,来看下在不同的 n n n 的情况下, f ( n ) f(n) f(n) 这个函数会被调用几次;
  • 实测下来的表格如下:
n n n f ( n ) f(n) f(n) c [ n ] c[n] c[n]
011
111
223
335
459
5815
61325
72141
83467
955109
1089177
11144287
12233465
13377753
146101219
159871973
1615973193
1725845167
1841818361
19676513529
201094621891
211771135421
222865757313
234636892735
2475025150049
25121393242785
26196418392835
27317811635621
285142291028457
  • 观察 c [ n ] c[n] c[n] 的增长趋势,首先排除等差数列,然后再来看是否符合等比数列,我们来尝试求下 c [ n ] / c [ n − 1 ] c[n] / c[n-1] c[n]/c[n1] 的值,列出表格如下:
n n n f ( n ) f(n) f(n) c [ n ] c[n] c[n] c [ n ] / c [ n − 1 ] c[n]/c[n-1] c[n]/c[n1]
1111.000000
2233.000000
3351.666667
4591.800000
58151.666667
613251.666667
721411.640000
834671.634146
9551091.626866
10891771.623853
111442871.621469
122334651.620209
133777531.619355
1461012191.618858
1598719731.618540
16159731931.618348
17258451671.618227
18418183611.618154
196765135291.618108
2010946218911.618080
2117711354211.618062
2228657573131.618051
2346368927351.618045
24750251500491.618041
251213932427851.618038
261964183928351.618037
273178116356211.618036
2851422910284571.618035
  • 观察发现,随着 n n n 的不断增大, c [ n ] / c [ n − 1 ] c[n]/c[n-1] c[n]/c[n1] 越来越接近一个常数,而这个常数就是:
    2 5 − 1 ≈ 1.618034 \frac {2}{ \sqrt 5 - 1} \approx 1.618034 5 121.618034
  • 当 n 趋近于无穷大的时候,满足如下公式:
    c [ n ] = 2 5 − 1 c [ n − 1 ] c[n] = \frac {2}{ \sqrt 5 - 1} c[n-1] c[n]=5 12c[n1]
  • 对等比数列化解后累乘得到:
    c [ n ] = 2 5 − 1 c [ n − 1 ] = ( 2 5 − 1 ) 2 c [ n − 2 ] = . . . = ( 2 5 − 1 ) n c[n] = \frac {2}{ \sqrt 5 - 1} c[n-1] = (\frac {2}{ \sqrt 5 - 1})^2 c[n-2] = ... = (\frac {2}{ \sqrt 5 - 1})^n c[n]=5 12c[n1]=(5 12)2c[n2]=...=(5 12)n
  • 所以,斐波那契数列 递归求解的时间复杂度就是 :
    O ( ( 2 5 − 1 ) n ) O((\frac {2}{ \sqrt 5 - 1})^n) O((5 12)n)
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页