简体   繁体   中英

How does this implementation of Fibonacci(n) work? [recursion]

Theres an exercise from a Java book I'm reading that has me confused:

A Fibonacci sequence is the sequence of numbers 1, 1, 2, 3, 5, 8, 13, 21, 34, etc., where each number (from the third on) is the sum of the previous two. Create a method that takes an integer as an argument and displays that many Fibonacci numbers starting from the beginning. If, eg, you run java Fibonacci 5 (where Fibonacci is the name of the class) the output will be: 1, 1, 2, 3, 5.

I could have swore that it would need an array or some way of storing the previous numbers but when I saw the answer it wasn't the case:

import java.util.*; 

public class Fibonacci { 

    static int fib(int n) {
         if (n <= 2) 
              return 1;

         return fib(n-1) + fib(n-2);
    } 
    public static void main(String[] args) {
    // Get the max value from the command line: 
    int n = Integer.parseInt(args[0]); 
    if(n < 0) {
        System.out.println("Cannot use negative numbers"); return;
    } 
    for(int i = 1; i <= n; i++)
        System.out.print(fib(i) + ", ");
    }
}

Would someone be able to explain how using a function within itself produces this?

The code you gave is an example of a recursive solution. When the function is called for the first time, it executes until it calls itself. Its state is stored on the stack, and the code begins executing again with new input data. This process repeats until the input is less than 2, at which point 1 is returned, and the answer returns to the previous caller.

For example, calling fib(5) results in the following execution:

fib(5):
    fib(4):
        fib(3):
            fib(2): 1
            fib(1): 1
        fib(2): 1
    fib(3):
        fib(2): 1
        fib(1): 1

Note that you are partially correct. Intermediate results are stored on the stack in this solution. That is one of the reasons why the recursive solution is so expensive. The other is its O(2^n) complexity. However, if is possible to compute Fibonacci(n) iteratively and without storing all previous results. All you really need is to store the last to results and count from 1 up to n .

                           F(n)
                            /    \
                        F(n-1)   F(n-2)
                        /   \     /      \
                    F(n-2) F(n-3) F(n-3)  F(n-4)
                   /    \
                 F(n-3) F(n-4)

Important point to note is this algorithm is exponential because it does not store the result of previous calculated numbers. eg F(n-3) is called 3 times.

For more details refer algorithm by dasgupta chapter 0.2

This is a recursive solution. A recursive function calls itself until a given stop condition is met. Then each call exits until only the first call remains. That first call outputs the result.

In your solution, the stop condition is :

if (n <= 2) 
          return 1;

until this condition is met, the function will make successive calls to itself. Each call reduces the int passed as a parameter. When it reaches 2, the stop condition dictates that the function returns with value 1 (the result of n=1 and n=2 in fibonacci(n) ).

Because the fibonacci is the sum of the last two numbers, the recursive part of the function,

return fib(n-1) + fib(n-2);

does a sum of n-1 and n-2 (as I said, the two last numbers of the sequence). When the n equals 2, these calls to function fib will finally have a value, and will be returned.

Example, if n = 3, the recursive part will call fib(2) and fib(1), both are equal or less than 2, so both calls will return 1. So the printf will print 1, 1, 2. 2 is the sum of 1 + 1 (I know it's obvious, but sometimes stating the obvious helps).

This is the standard example for an recursive function .

The Fibonacci Numbers are declared recursive, too.

Both fib(1) and fib(2) are declared as 1. All others are calculated by adding the last two fibonacci numbers, so fib(3)=fib(2)+fib(1) .

Compare this to the calculation method which does exactly this:

static int fib(int n) {
     if (n <= 2) 
          return 1;

     return fib(n-1) + fib(n-2);
} 

By the way, this is a very slow way to calculate the fibonacci numbers, using two variables (you don't need all of them for the last one, only the last two!) and a loop is in O(n), the recursive function above has O(2^n) operations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM