2

I'm trying to clarify the order in which recursive calls get executed. I read through this link: Dynamic programming and Divide and conquer

The function was written like this:

int Fibonacci(int n) {
    if (n <= 1) return n;

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

The call order was described like this:

If you trace out the calls done to compute Fibonacci(4), we get
Fibonacci(4) calls Fibonacci(3) and Fibonacci(2)
Fibonacci(3) calls Fibonacci(2) and Fibonacci(1)
Fibonacci(2) calls Fibonacci(1) and Fibonacci(0)
Fibonacci(2) (the other one) calls Fibonacci(1) and Fibonacci(0)
Fibonacci(1) terminates.
Fibonacci(1) terminates.
Fibonacci(1) terminates.
Fibonacci(0) terminates. Fibonacci(0) terminates.

This brings up two questions:

(1) For this code:

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

Does the call on the left-hand-side of the + sign always get called before the call on the right hand side? I think we get some sort of depth-first chain of function calls, where the straight line call Fib(5)...Fib(4)...Fib(3)...Fib(2)...Fib(1) gets called in a row before anything else gets called in the tree branching process. Is that true?

(2) I'm not understanding why the branches terminate in this order: Fibonacci(1) terminates. Fibonacci(1) terminates. Fibonacci(1) terminates. Fibonacci(0) terminates. Fibonacci(0) terminates.

I thought the termination order would simply be the leaf-order from left-to-right at the bottom of the tree: 1 0 1 1 0

Thanks for any insights on this.

Community
  • 1
  • 1
code beginner
  • 285
  • 3
  • 14

2 Answers2

0

I guess you are right. I just did a small test:

int fibo(int n) {
    if (n <= 1) return n;
    System.out.println("fibo " + n + " calls fibo " + (n - 1) + " and fibo " + (n - 2));
    int f1 = fibo(n - 1);
    System.out.println("fibo " + (n - 1) + " terminates");
    int f2 = fibo(n - 2);
    System.out.println("fibo " + (n - 2) + " terminates");
    return f1 + f2;
}

And got:

fibo 4 calls fibo 3 and fibo 2
fibo 3 calls fibo 2 and fibo 1
fibo 2 calls fibo 1 and fibo 0
fibo 1 terminates
fibo 0 terminates
fibo 2 terminates
fibo 1 terminates
fibo 3 terminates
fibo 2 calls fibo 1 and fibo 0
fibo 1 terminates
fibo 0 terminates
fibo 2 terminates

As you can see, the termination sequence for the base cases is 1 0 1 1 0.

Anderson Vieira
  • 8,919
  • 2
  • 37
  • 48
0

You didn't specify a language, so the order of invocation isn't guaranteed when you have two calls on a single line. Some languages or compilers specify what they'll do, others don't.

Assuming left-to-right evaluation, I broke things up into explicit calls with print statements to show explicitly where things happen. Since no language was specified I did this in Ruby:

def fib(n)
  return n if n <= 1 
  puts "fib(#{n}) calls fib(#{n-1})"
  f1 = fib(n-1)
  puts "fib(#{n-1}) returns to fib(#{n})"
  puts "fib(#{n}) calls fib(#{n-2})"
  f2 = fib(n-2)
  puts "fib(#{n-2}) returns to fib(#{n})"
  f1 + f2
end

It produced the following output:

irb(main):011:0> fib(4)
fib(4) calls fib(3)
fib(3) calls fib(2)
fib(2) calls fib(1)
fib(1) returns to fib(2)
fib(2) calls fib(0)
fib(0) returns to fib(2)
fib(2) returns to fib(3)
fib(3) calls fib(1)
fib(1) returns to fib(3)
fib(3) returns to fib(4)
fib(4) calls fib(2)
fib(2) calls fib(1)
fib(1) returns to fib(2)
fib(2) calls fib(0)
fib(0) returns to fib(2)
fib(2) returns to fib(4)
=> 3

which I think makes pretty clear what's being done, and in what order.

pjs
  • 18,696
  • 4
  • 27
  • 56