斐波那契数列第 n 项的值与递归树节点个数的关系证明

斐波那契数列第 n 项的值 f i b ( n ) fib(n) fib(n) 与递归树节点个数 G ( n ) G(n) G(n) 的关系证明:

先上结论: G ( n ) = 2 f i b ( n + 1 ) − 1 G(n)=2fib(n+1)-1 G(n)=2fib(n+1)1

我们先看一下斐波那契数列的定义,如下:
f i b ( n ) = { 0 , n = 0 1 , n = 1 f i b ( n − 1 ) + f i b ( n − 2 ) , n ≥ 2 \begin{aligned} fib(n)= \begin{cases} 0&,n=0\\ 1&,n=1\\ fib(n-1)+fib(n-2)&,n\ge2 \end{cases} \end{aligned} fib(n)=01fib(n1)+fib(n2),n=0,n=1,n2
先由公式算出几个值,有:
f i b ( 0 ) = 0 , f i b ( 1 ) = 1 , f i b ( 2 ) = 1 , f i b ( 3 ) = 2 , f i b ( 4 ) = 3 , f i b ( 5 ) = 5 , f i b ( 6 ) = 8 \begin{aligned} fib(0)=0, fib(1)=1, fib(2)=1, fib(3)=2, fib(4)=3, fib(5)=5, fib(6)=8 \end{aligned} fib(0)=0fib(1)=1fib(2)=1fib(3)=2fib(4)=3fib(5)=5fib(6)=8

以下是暴力递归实现斐波那契数列:

public static int fib(int n) {
    
    
    if (n == 0 || n == 1) {
    
    
        return n == 0 ? 0 : 1;
    } else if (n < 0) {
    
    
        throw new RuntimeException("请输入大于等于0的数");
    }
    return fib(n - 1) + fib(n - 2);
}

以下是该算法求解的递归树。

在这里插入图片描述

G ( n ) G(n) G(n) f i b ( n ) fib(n) fib(n) 的递归树中节点个数,也就是说 G ( n ) G(n) G(n) 是调用该函数的次数。

看到该递归树,容易得出:
G ( 0 ) = 1 , G ( 1 ) = 1 , G ( 2 ) = 3 , G ( 3 ) = 5 , G ( 4 ) = 9 , G ( 5 ) = 15 \begin{aligned} G(0)=1, G(1)=1, G(2)=3, G(3)=5, G(4)=9, G(5)=15 \end{aligned} G(0)=1G(1)=1G(2)=3G(3)=5G(4)=9G(5)=15

由数学归纳法容易证明
G ( n ) = G ( n − 1 ) + G ( n − 2 ) + 1 , n ≥ 2 G(n)=G(n-1)+G(n-2)+1,n\ge2 G(n)=G(n1)+G(n2)+1n2
约定 T ( n ) = O ( G ( n ) ) T(n)=O(G(n)) T(n)=O(G(n))
则有:
G ( n ) = G ( n − 1 ) + G ( n − 2 ) + 1 = 2 G ( n − 2 ) + G ( n − 3 ) + 1 + 1 = 3 G ( n − 3 ) + 2 G ( n − 4 ) + 1 + 1 + 2 ⋮ = f i b ( k + 1 ) T ( n − k ) + f i b ( k ) T ( n − ( k + 1 ) ) + ∑ i = 0 k f i b ( i ) \begin{aligned} G(n)=&G(n-1)+G(n-2)+1\\ =&2G(n-2)+G(n-3)+1+1\\ =&3G(n-3)+2G(n-4)+1+1+2\\ \vdots\\ =&fib(k+1)T(n-k)+fib(k)T(n-(k+1))+\sum_{i=0}^{k}fib(i)\\ \end{aligned} G(n)====G(n1)+G(n2)+12G(n2)+G(n3)+1+13G(n3)+2G(n4)+1+1+2fib(k+1)T(nk)+fib(k)T(n(k+1))+i=0kfib(i)

我们知道该数列的递推式如下:
f i b ( n ) = f i b ( n − 1 ) + f i b ( n − 2 ) , n ≥ 2 fib(n)=fib(n-1)+fib(n-2),n\ge2 fib(n)=fib(n1)+fib(n2),n2

现将其作差使用累加法求和,过程如下:
f i b ( n ) − f i b ( n − 1 ) = f i b ( n − 2 ) f i b ( n − 1 ) − f i b ( n − 2 ) = f i b ( n − 3 ) ⋮ f i b ( 2 ) − f i b ( 1 ) = f i b ( 0 ) \begin{aligned} &fib(n)-fib(n-1)=fib(n-2)\\ &fib(n-1)-fib(n-2)=fib(n-3)\\ &\vdots\\ &fib(2)-fib(1)=fib(0) \end{aligned} fib(n)fib(n1)=fib(n2)fib(n1)fib(n2)=fib(n3)fib(2)fib(1)=fib(0)
得到以下式子:
f i b ( n ) − 1 = ∑ i = 0 n − 2 f i b ( i ) fib(n)-1=\sum_{i=0}^{n-2}fib(i) fib(n)1=i=0n2fib(i)

n = k + 2 n=k+2 n=k+2 ,即有
∑ i = 0 k f i b ( i ) = f i b ( k + 2 ) − 1 \sum_{i=0}^{k}fib(i)=fib(k+2)-1 i=0kfib(i)=fib(k+2)1

ok,到这里,一切都准备就绪,接着把 G ( n ) G(n) G(n) 公式写下去就好了。

那么,现在令 k = n − 1 k=n-1 k=n1,则

G ( n ) = f i b ( k + 1 ) T ( n − k ) + f i b ( k ) T ( n − ( k + 1 ) ) + ∑ i = 0 k f i b ( i ) = f i b ( k + 1 ) T ( 1 ) + f i b ( k ) T ( 0 ) + f i b ( k + 2 ) − 1 = f i b ( k + 1 ) + f i b ( k ) + f i b ( k + 2 ) − 1 = 2 f i b ( k + 2 ) − 1 = 2 f i b ( n + 1 ) − 1 \begin{aligned} G(n)=&fib(k+1)T(n-k)+fib(k)T(n-(k+1))+\sum_{i=0}^{k}fib(i)\\ =&fib(k+1)T(1)+fib(k)T(0)+fib(k+2)-1\\ =&fib(k+1)+fib(k)+fib(k+2)-1\\ =&2fib(k+2)-1\\ =&2fib(n+1)-1 \end{aligned} G(n)=====fib(k+1)T(nk)+fib(k)T(n(k+1))+i=0kfib(i)fib(k+1)T(1)+fib(k)T(0)+fib(k+2)1fib(k+1)+fib(k)+fib(k+2)12fib(k+2)12fib(n+1)1

举个例子,由递归树图中可以看出 G ( 5 ) = 15 G(5)=15 G(5)=15

用公式算出 G ( 5 ) = 2 f i b ( 6 ) − 1 = 2 × 8 − 1 = 15 G(5)=2fib(6)-1=2\times8-1=15 G(5)=2fib(6)1=2×81=15

可以看出该公式是正确的。

也就是说该暴力递归调用函数的次数为后一个值的 2 倍减 1

猜你喜欢

转载自blog.csdn.net/lhrfighting/article/details/120987078