2

I have the next method:

public static int maxFind(int [] a, int length)
{
  if (length == 1){
          return a[0];
  }

  // recursively maxFind method on length-1
  int result = maxFind(a, length - 1);

  if (a[length - 1] > result)
    return a[length - 1];
  else
    return result;

}

I've finished that work, and pass some time from when i saw a tutorial of that method and i always forget the idea of recursion. i think that if someone will explain me every step of this method - i will get the idea once for all.

Example - my arr is: {1,1,0,2)

What is the steps here when we running this method? what is the value on result, and what is the role of (a, length-1) ? (i've tried the debugger but it's not helped me)

Oshrib
  • 1,789
  • 12
  • 40
  • 67

4 Answers4

5

Let me see if I can shed some light on the subject.

When thinking about recursion, it helps (me at least), to think about the program in a more declarative way, meaning, you think about what you're trying to accomplish, instead of thinking about each step of the algorithm needed to accomplish it.

Let's check your example, you need to find the max value in an Array, so we'll break down this problem in smaller problems.

If the size of the Array is 1, there's only one element... so that one is the maximum. Easy.

The problem of finding the max can be described as: The greater value between one element of the list, and the maximum of all the other elements.

That's what you're doing in the rest of the code. You apply the algorithm to the array from the position 0 to length-1, and then compare the returning value.

These calls will create a Recursion Tree, meaning, there will be several calls "nested", until each call is done with length=1 (the base case), and then, the algorithm will start reconstructing the answer.

The best way of really understanding a recursive algorithm is to grab a piece of paper and emulate the program, write the values of your array and the value of "length" on the paper for each call, and then figure out what happens after each call finally reaches a base case.

For {1,1,0,2}, you'll basically get a chain of calls, something like:

max(maxFind({1,1,0}), 2)

Where maxFind({1,1,0}) boils down to:

max(maxFind({1,1}), 0)

and maxFind({1,1}) is

max(1,1)  = 1

Then this starts boiling up (it's the reverse order from above):

max(1, 0) = 0
max(1, 2) = 2 

So the result will be 2.

pcalcao
  • 15,789
  • 1
  • 44
  • 64
  • thanks for the detailed answer. i've took paper and done it, but i stacked on the end. let me see if i was'nt wrong. at the end we got (by my array - 1,1,0,2) the question from the if statment if (a[0] (=1) > result(=1)... right? so how the method remember that the max value on result was 2? or i wrong on my tree that i made on the paper. sorry for the english :) – Oshrib Jan 06 '12 at 10:34
3

I'll try to explain step by step :

At first you call the method with parameters {1,1,0,2} and 4

1) max_find([1,1,0,2],4) => length is not 1 so max_find will be called again with length=4-1

2) max_find([1,1,0,2],3) => length is not 1 so max_find will be called again with length=3-1

3) max_find([1,1,0,2],2) => length is not 1 so max_find will be called again with length=2-1

4) max_find([1,1,0,2],1) => length is 1, so a[0] will be returned which is 1

5) now the code form step 3 evaluates the result from step 4 => a[2-1] is not > 1, so it returns 1

6) now the code form step 2 evaluates the result from step 3 => a[3-1] is not > 1, so it returns 1

7) now the code form step 1 evaluates the result from step 2 => a[4-1] is > 1, so it returns a[4-1] which is 2

done

Don
  • 1,134
  • 8
  • 15
2

what is the value on result

Well that's the point of recursion: there's not one value of result, which may be what is confusing you. Result's value is, in order, 1, 1, 1 then 2.

What is the steps here when we running this method?

Here's what happens:

What is the max of: {1} ?  Result is: 1   
What is the max of: {(1), 1} ?  Result is: 1
What is the max of: {(1, 1), 0} ?  Result is: 1
What is the max of: {(1, 1, 0), 2} ?  Result is: 2

Note that debugging is indeed not that trivial when working with recursive methods. It sometimes helps much more to print the method calls "indented" to the depth recursion level, like in this question I answered here:

How do I solve the 'classic' knapsack algorithm recursively?

(of course you need to somehow keep track of the 'depth' of the recursive calls)

and what is the role of (a, length-1) ? (i've tried the debugger but it's not helped me)

The debugger may not be helping you because that method is using a 'trick' in order to save memory in Java: basically the input is shortened by indicating that you shouldn't parse the entire array. But you're still recursively passing the entire array to the method. This is a "poor man's functional way of getting a list with one less element" ; )

Here's a link showing how to find the maximum value of a list in a lot of different language. Some of them, like the OCaml one, are expressed in a functional form:

http://rosettacode.org/wiki/Greatest_element_of_a_list

Three lines of OCaml (source: Wikipedia):

let my_max = function
    [] -> invalid_arg "empty list"
  | x::xs -> List.fold_left max x xs
Community
  • 1
  • 1
TacticalCoder
  • 6,275
  • 3
  • 31
  • 39
  • 1
    if i was able to choose 2 right answerd... you and pcalcao and don are greats. thanks !!! – Oshrib Jan 06 '12 at 11:10
1

The idea is basically that you do exactly the same stuff again with just a little change of the input data.

The code itself is easy:

  • The first if checks for the recursion end
  • the int result line does the recursion
  • at the end you lookes for the biggest element and returns it.
rekire
  • 47,260
  • 30
  • 167
  • 264