Java Notes: 15.1 Learning Outcomes
Java Notes: 15.1 Learning Outcomes
JAVA NOTES
15 RECURSION
15.2 PRE-REQUISITES
The student should be comfortable with using arrays and the linear search, binary search and
selection sort methods.
15.3 INTRODUCTION
15.4 POWER
In general, 2n = 2 × 2n-1
provided n is an integer >= 0.
Now we can write the Java method to return the value of two raised to some power, n.
A recursive method is one that calls itself. The powerOfTwo(int n) method described above
makes a call to itself in powerOfTwo(n-1).
(a) the simple case that ends the sequence of recursive calls and
(b) the recursive step, that is always one step closer to the simple case
Just to emphasise the principles, let us trace the sequence of method calls resulting from
System.out.println(powerOfTwo(3));.
128
powerOfTwo(3)
n=3
int powerOfTwo(int n)
{
if (n == 0)
return 1;
else if (n > 0) frame 1
return 2 * powerOfTwo(n-1);
}
n=2
int powerOfTwo(int n)
{
if (n == 0)
return 1;
else if (n > 0) frame 2
return 2 * powerOfTwo(n-1);
}
n=1
int powerOfTwo(int n)
{
if (n == 0)
return 1;
else if (n > 0)
frame 3 return 2 * powerOfTwo(n-1);
}
n=0
int powerOfTwo(int n)
{
if (n == 0)
return 1;
frame 4 else if (n > 0)
return 2 * powerOfTwo(n-1);
}
129
In general, calculation and return is suspended until the result from the next recursive call is
obtained.
The method contains() shown below performs a recursive linear search on an array of ints for
a given int, target. It searches through the array from the given fromIndex up to the given
toIndex inclusive.
The simple case occurs when fromIndex exceeds toIndex; then target is not in the array.
array[fromIndex] == target
before going on to search the rest of the array with the recursive call contains(array,
fromIndex+1, toIndex, target). The recursive call brings you one step closer to the simple
case. Since each call adds 1 to fromIndex there must come a time when fromIndex exceeds
toIndex.
false || false || true || false || false being evaluated. The end result, of course, is true.
131
The binarySearch() method shown below is implemented using recursion. The method sorts
the given array of ints between the given indices, lo and hi.
There are two simple cases that terminate the sequence of recursive calls.
If lo exceeds hi then there is nothing left to search and the target, the int we are looking for, is
not in the array.
If the target is in the middle location of the array, then we have found what we were looking
for.
There are two possible recursive calls, each one a step closer to a simple case.
binarySearch(array, lo, middle-1, target) searches the left-hand part of the array.
binarySearch(array, middle+1, hi, target) searches the right hand part of the array.
We have two helper methods. swap() exchanges the values in the array at two given indices,
i and j. minLocation() returns the location of the least value in the give array between the two
indices from and to inclusive.
The simple case occurs when from exceeds to; there is no more array to sort.
Each recursive call brings you one step closer to the simple case. For each recursive call
made, from is advanced by one so there is successively smaller and smaller portions of the
array from which to select the least value and place it in its correct position.
15.8 REVIEW
In the next lesson we use recursion to implement binary search tree operations.
15.10 EXERCISES
1 Trace the sequence of recursive method calls for method Q shown below when the first
call to method Q is System.out.println(Q(5));
2 Trace the sequence of recursive method calls for method X shown below when the first
call to method X is System.out.println(sum(2, 3)); Hence (or otherwise) give a descriptive
name to X.
3 Trace the sequence of recursive method calls for method Y shown below for each of
4 Develop and test a method that uses recursion to determine the result of mn where m and n
are both integers >= 0.
5 Test the recursive linear search method defined in §15.5 above. Remember to carefully
check boundaries.
6 Thoroughly test the recursive binary search method defined in §15.6 above (see §5.5).
Which implementation, the iterative one described in §5 .4 or the recursive one, do you find
easier to understand? Explain why.