Understanding double recursion

It seems to me that you have confused the running order of the recursive calls. Keep in mind that, second call (maxval2) does not get called until the first call (maxval1) finishes. maxval1 call itself has two more recursive calls within itself and so on. So without all these inner recursive calls being finished, the program does not reach the maxval2 line.

Try debugging instead of running the code (in Eclipse for e.g.) and move step by step to see how it actually goes about each recursive call.


I'm not sure if I'll be able to explain it very well, but I'll explain it using fibonacci instead. A recursive way for calculating fibonacci numbers are:

public static int getFib(int n) {
    if(n <= 2) return 1;
    return getFib(n-1)+getFib(n-2);
}

What actually happens in the code is that it will obviously go down the method calls until it gets a first return. So getFib(n-1) will keep getting called until n <= 2 then it will go back up the method stack and since it now has a value for that getFib(n-1) it will call the getFib(n-2). So say our initial call is with 4, what happens is:

getFib(4) //Initial call
  getFib(4-1=3) //Left hand recursive call level 1
    getFib(3-1=2) //Left hand recursive call level 2
      return 1 //This would be level 3
    getFib(3-2=1) //Right hand recursive call level 2
      return 1 //level 3
  getFib(4-2=2) //Right hand recursive call level 1
    return 1

Not sure if that makes any sense, this image might visualise it a bit: Recursive fibonacci tree
(source: fortystones.com)

The above code would basically make a depth first (taking the left children first) traversal through that tree.


It sounds like you already understand the base case and know how recursion works, so the key to understanding your particular example is to note that given the initial array

a = [1,2,10,15,16,4,8]

you are, at the "top level" computing two things:

maxval1 = MaximumElement(array, 0, 3); 
maxval2 = MaximumElement(array, 3, 4);

which says

  • make maxval1 the maximum value from the array in the range starting from index 0 of size 3
  • make maxval2 the maximum value from the array in the range from index 3 of size 4

So

  • maxval1 will indeed be 10
  • maxval2 will indeed be 16

and your answer will be 16.

The nice thing about recursion is that you don't have to worry about tracing things too extensively. If you trust your base case and the manner in which you get to your base case, then understanding one level should suffice.

I think you got stuck where you said "all hell breaks loose" because the second recursive call begins with a starting index of 0. It doesn't. It starts at index 3. (That is, assuming your second recursive call is the one computing maxVal2).

Here is a bit of an abbreviated trace of how your computation works out. I've taken the liberty to rename your function to m and to assume that maxVal1 and maxVal2 were computed a little more "functionally".

a = [1,2,10,15,16,4,8]

m(a, 0, 7)
= m(m(a, 0, 3), m(a, 3, 4))
= m(m(m(a, 0, 1), m(a, 1, 2)), m(a, 3, 4))
= m(m(a[0], m(a, 1, 2)), m(a, 3, 4))
= m(m(1, m(a, 1, 2)), m(a, 3, 4))
= m(m(1, m(m(a, 1, 1), m(a, 2, 1)), m(a, 3, 4))
= m(m(1, m(a[1], a[2])), m(a, 3, 4))
= m(m(1, m(2, 10)), m(a, 3, 4))
= m(m(1, 10), m(a, 3, 4))
= m(10, m(a, 3, 4))
= …
= 16