Fast recursive function to return the nth Fibonacci number

Can someone explain how the following code works. The code was provided as a fast recursive implementation of a function that returns the nth Fibonacci number. I have a general idea of ​​how recursive functions work. I can fully understand the direct recursive implementation of such a function using the definition of Fibonacci numbers, which, however, is inefficient. The main thing I can’t understand is what fib (n - 1, prev0) returns when we have garbage stored in prev0.

int fib(int n, int &prev1) {
    if (n < 2) {
        prev1 = 0;
        return n;
    }
    int prev0;
    prev1 = fib(n – 1, prev0);
    return prev0 + prev1;
}

I'm a newbie, so please be as specific as possible.

+4
source share
4 answers

, , : "", .

fib , , .

, "", "", .

"" (- ). , fib, .

, ++ . ( C ).

( ):

, , , fib (n - 1, prev0) , prev0.

, prev0 - , .

, , , .

int & . .

, , n prev0. prev1 . prev0. , prev1 prev0.

n " ", ( n-1). prev1 , prev0, prev0.

+2

, prev1 . . :

std::pair<int,int> fib_pair(int n) {
    if (n < 2) {
        return std::make_pair(n, 0);
    }

    std::pair<int, int> prev = fib_pair(n-1);
    return std::make_pair(prev.first + prev.second, prev.first);
}

- , fib(n) , . . , :

int fib(int n, int &prev1) {
    std::pair<int, int> pair = fib_pair(n);
    prev1 = pair.second;
    return pair.first;
}
+2

, n , . :

function fib(n) # exponential
    if n <= 2 return 1
    return fib(n-1) + fib(n-2)

, O (2 n), . O (n), 1 n n 1 :

function fib(n) # linear
    if n <= 2 return 1
    prev2 = prev1 = 1
    k := 3
    while k <= n
        fib := prev2 + prev1
        prev2 := prev1
        prev1 := fib
    return fib

, , , , .

Dijkstra n , O (log n), , ; Dijkstra , ( , F 0= 1 F 0= 0, ). :

function fib(n) # logarithmic
    if n <= 2 return 1
    n2 := n // 2 # integer division
    if n % 2 == 1 return square(fib(n2+1)) + square(fib(n2))
    return fib(n2) * (2*fib(n2-1) + fib(n2))

, O (1), , :

function fib(n) # constant
    sqrt5 := sqrt(5)
    p := (1 + sqrt5) / 2
    q := 1 / p
    return floor((p**n + q**n) / sqrt5 + 0.5)

, - , , , , - , , , n .

+2

() :

int fib(int n) {
    if (n<2) return n;
    return fib(n-2) + fib(n-1);
}

, .

For example, if n is 6, you will be presented with an algorithm for adding fib (4) and fib (5). To find fib (5), you need to add fib (4) and fib (3). And there you calculate fib (4) for the second time. As n increases, this becomes more inefficient.

In your example, this inefficiency is avoided by remembering the previous fibonacci sequence.

0
source

Source: https://habr.com/ru/post/1606472/


All Articles