文章目录
一、斐波那契数列
- 所谓斐波那契数列,是指【当前项】的值等于【前两项】之和的数列:
| i i i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|
| f ( i ) f(i) f(i) | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 |
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(n−1)+f(n−2)(n=0)(n=1)(n>2)
二、递归求解斐波那契数列
int f(unsigned int n) {
if(n <= 1) {
return 1;
}
return f(n-1) + f(n-2);
}
三、时间复杂度分析
- 这是一棵二叉树,树的高度为 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] |
|---|
| 0 | 1 | 1 |
| 1 | 1 | 1 |
| 2 | 2 | 3 |
| 3 | 3 | 5 |
| 4 | 5 | 9 |
| 5 | 8 | 15 |
| 6 | 13 | 25 |
| 7 | 21 | 41 |
| 8 | 34 | 67 |
| 9 | 55 | 109 |
| 10 | 89 | 177 |
| 11 | 144 | 287 |
| 12 | 233 | 465 |
| 13 | 377 | 753 |
| 14 | 610 | 1219 |
| 15 | 987 | 1973 |
| 16 | 1597 | 3193 |
| 17 | 2584 | 5167 |
| 18 | 4181 | 8361 |
| 19 | 6765 | 13529 |
| 20 | 10946 | 21891 |
| 21 | 17711 | 35421 |
| 22 | 28657 | 57313 |
| 23 | 46368 | 92735 |
| 24 | 75025 | 150049 |
| 25 | 121393 | 242785 |
| 26 | 196418 | 392835 |
| 27 | 317811 | 635621 |
| 28 | 514229 | 1028457 |
- 观察 c [ n ] c[n] c[n] 的增长趋势,首先排除等差数列,然后再来看是否符合等比数列,我们来尝试求下 c [ n ] / c [ n − 1 ] c[n] / c[n-1] c[n]/c[n−1] 的值,列出表格如下:
| 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[n−1] |
|---|
| 1 | 1 | 1 | 1.000000 |
| 2 | 2 | 3 | 3.000000 |
| 3 | 3 | 5 | 1.666667 |
| 4 | 5 | 9 | 1.800000 |
| 5 | 8 | 15 | 1.666667 |
| 6 | 13 | 25 | 1.666667 |
| 7 | 21 | 41 | 1.640000 |
| 8 | 34 | 67 | 1.634146 |
| 9 | 55 | 109 | 1.626866 |
| 10 | 89 | 177 | 1.623853 |
| 11 | 144 | 287 | 1.621469 |
| 12 | 233 | 465 | 1.620209 |
| 13 | 377 | 753 | 1.619355 |
| 14 | 610 | 1219 | 1.618858 |
| 15 | 987 | 1973 | 1.618540 |
| 16 | 1597 | 3193 | 1.618348 |
| 17 | 2584 | 5167 | 1.618227 |
| 18 | 4181 | 8361 | 1.618154 |
| 19 | 6765 | 13529 | 1.618108 |
| 20 | 10946 | 21891 | 1.618080 |
| 21 | 17711 | 35421 | 1.618062 |
| 22 | 28657 | 57313 | 1.618051 |
| 23 | 46368 | 92735 | 1.618045 |
| 24 | 75025 | 150049 | 1.618041 |
| 25 | 121393 | 242785 | 1.618038 |
| 26 | 196418 | 392835 | 1.618037 |
| 27 | 317811 | 635621 | 1.618036 |
| 28 | 514229 | 1028457 | 1.618035 |
- 观察发现,随着 n n n 的不断增大, c [ n ] / c [ n − 1 ] c[n]/c[n-1] c[n]/c[n−1] 越来越接近一个常数,而这个常数就是:
2 5 − 1 ≈ 1.618034 \frac {2}{ \sqrt 5 - 1} \approx 1.618034 5 −12≈1.618034
- 当 n 趋近于无穷大的时候,满足如下公式:
c [ n ] = 2 5 − 1 c [ n − 1 ] c[n] = \frac {2}{ \sqrt 5 - 1} c[n-1] c[n]=5 −12c[n−1]
- 对等比数列化解后累乘得到:
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[n−1]=(5 −12)2c[n−2]=...=(5 −12)n
- 所以,斐波那契数列 递归求解的时间复杂度就是 :
O ( ( 2 5 − 1 ) n ) O((\frac {2}{ \sqrt 5 - 1})^n) O((5 −12)n)