KEMBAR78
Recursion Lecture in Java | PDF
Recursion lecture in Java
Recursively breaking down a problem into two or more sub-problems of the
same (or related) type, until these become simple enough to be solved directly.
The solutions to the sub-problems are then combined to give a solution to the
original problem.
Top-Down Design
Cleaning apartment/house.
Example
Divide and Conquer Algorithm
Many divide and conquer type algorithms can be implemented as recursive
functions.
Condition that leads to a recursive method returning without making another
recursive call.
Stops the recursion.
Solution to this case is simple enough to solve directly.
Base case.
Calls itself to solve smaller sub-problems.
May combine the results of the sub-problems.
Properties of recursive functions
Recursive methods
/**
* This is the recursive form of arithmetic series
* x = x + (x-1) + (x-2) + .. + 0
*/
public class ArthmeticSeries {
public static void main(String[] args) {
int sum = arthmeticSeries(2);
System.out.println(sum);
}
private static int arthmeticSeries(int x) {
//base case.
if (x == 0)
return 0;
Example: Arithmetic Series
//base case.
if (x == 0)
return 0;
//recursive case.
return x + arthmeticSeries(x - 1);
}
}
Example: cafeteria plates.
A stack is a FIFO data structure.
Each method call produces a stack frame (like a plate).
Information about the method.
Method arguments.
Information on how to return to the caller.
Each frame consists of:
What does recursion look like on the call stack?
The Fibonacci sequence a(1), a(2), a(3), ..., a(n), ... is defined by
a(1) =1
a(2) = 1
a(n) = a(n-1) + a(n-2)
, for all n > 2
This generates the sequence:
1, 1, 2, 3, 5, 8, 13, 21, ...
fibonacci(7) == 13
public class Fibonacci {
public static void main(String[] args) {
int num = fib(7);
System.out.println(num);
}
private static int fib(int x) {
if (x == 0)
return 0;
if (x == 1)
return 1;
Example: Fibonacci sequence
return 0;
if (x == 1)
return 1;
return fib(x - 1) + fib(x - 2);
}
}
public class BinarySearch {
public static void main(String[] args) {
int myArray[] = {41, 62, 77, 80, 85, 92, 104, 211, 400};
int pos = binsearch(myArray, 0, myArray.length, 62);
System.out.println(pos);
pos = binsearch(myArray, 0, myArray.length, 97);
System.out.println(pos);
}
private static int binsearch(int arr[], int start, int end, int val)
{
if ( start > end ) //if empty.
return -1; //not found.
int mid = (start + end) / 2;
if ( arr[ mid ] == val )
return mid; //found it!
else if ( arr[ mid ] < val )
return binsearch(arr, mid + 1, end, val);
else //arr[ mid ] > val
return binsearch(arr, start, mid - 1, val);
}
}
ex: 41 62 77 80 85 92 104 211 400
- search for 62
- check index 4 ((0+8)/2)
- (0+3)/2
- report found
- search for 97
- 97 > 85
- (5+8)/2 = 6
- 97 < 104
- (5+5)/2 = 5
- 97 > 92
Example: Binary Search
- (5+8)/2 = 6
- 97 < 104
- (5+5)/2 = 5
- 97 > 92
- use low and high index values to find that there are no more values to
search
Consider the sorting problem. That is, given a list of comparable
items (say an array of {bf int}s) in arbitrary order, rearrange that list
of items so that they are in {it non-decreasing} order. For example, say
you have an array of {bf int}s: $langle 38, 27, 43, 3, 9, 82, 10
rangle$. A sorted version of this array would be $langle 3, 9, 10, 27,
38, 43, 82 rangle$. Next, consider an efficient, divide and conquer
algorithm that can be used to {it recursively} solve the sorting problem
as follows:
begin{enumerate}
item Divide the unsorted list into two sublists of about half the
size.
item Divide each of the two sublists recursively until we have list
sizes of length $1$, in which case the list itself is returned
(after all, a list containing only $1$ element is always considered
sorted!).
item Merge the two sublists back into one sorted list.
end{enumerate}
Suppose now that you had the following function available to you:
begin{lstlisting}{}
void merge(Item arr[], const int& left, const int& right,
const int& pivot);
end{lstlisting}
that combines two {bf sorted} sub-arrays of {tt arr} (i.e., the inclusive
intervals [{tt left}, {tt pivot}] and [{tt pivot}$+1$, {tt right}]) to a
underline{single} {bf sorted} array. The result of this {it combined},
sorted array is stored back into {tt arr} to form a single, sorted array
whose valid elements are contained in the interval [{tt left}, {tt right}].
{tt Item} refers to a type (possibly through use of a {bf typedef}) whose
members are comparable (e.g., {bf int}).
/*
* 'a' is an array of 'Items' whose valid elements are between 'start' and 'end',
* inclusively. 'mid' is the position in 'a' in which to divide the array.
*/
void mergesort(Item a[], const int& start, const int& end, const int& mid) {
if ( start >= end ) //the array is either empty or contains a single element.
return; //sorting problem already solved. Nothing to do.
Example: Mergesort
if ( start >= end ) //the array is either empty or contains a single element.
return; //sorting problem already solved. Nothing to do.
//sort the left portion of the array.
mergesort(a, start, mid, (start + mid) / 2);
//sort the right portion of the array
mergesort(a, mid + 1, end, (mid + 1 + end) / 2);
//combined the two sorted array portions in a single sorted array.
merge(a, start, end, mid);
}

Recursion Lecture in Java

  • 1.
    Recursion lecture inJava Recursively breaking down a problem into two or more sub-problems of the same (or related) type, until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem. Top-Down Design Cleaning apartment/house. Example Divide and Conquer Algorithm Many divide and conquer type algorithms can be implemented as recursive functions. Condition that leads to a recursive method returning without making another recursive call. Stops the recursion. Solution to this case is simple enough to solve directly. Base case. Calls itself to solve smaller sub-problems. May combine the results of the sub-problems. Properties of recursive functions Recursive methods /** * This is the recursive form of arithmetic series * x = x + (x-1) + (x-2) + .. + 0 */ public class ArthmeticSeries { public static void main(String[] args) { int sum = arthmeticSeries(2); System.out.println(sum); } private static int arthmeticSeries(int x) { //base case. if (x == 0) return 0; Example: Arithmetic Series
  • 2.
    //base case. if (x== 0) return 0; //recursive case. return x + arthmeticSeries(x - 1); } } Example: cafeteria plates. A stack is a FIFO data structure. Each method call produces a stack frame (like a plate). Information about the method. Method arguments. Information on how to return to the caller. Each frame consists of: What does recursion look like on the call stack? The Fibonacci sequence a(1), a(2), a(3), ..., a(n), ... is defined by a(1) =1 a(2) = 1 a(n) = a(n-1) + a(n-2) , for all n > 2 This generates the sequence: 1, 1, 2, 3, 5, 8, 13, 21, ... fibonacci(7) == 13 public class Fibonacci { public static void main(String[] args) { int num = fib(7); System.out.println(num); } private static int fib(int x) { if (x == 0) return 0; if (x == 1) return 1; Example: Fibonacci sequence
  • 3.
    return 0; if (x== 1) return 1; return fib(x - 1) + fib(x - 2); } } public class BinarySearch { public static void main(String[] args) { int myArray[] = {41, 62, 77, 80, 85, 92, 104, 211, 400}; int pos = binsearch(myArray, 0, myArray.length, 62); System.out.println(pos); pos = binsearch(myArray, 0, myArray.length, 97); System.out.println(pos); } private static int binsearch(int arr[], int start, int end, int val) { if ( start > end ) //if empty. return -1; //not found. int mid = (start + end) / 2; if ( arr[ mid ] == val ) return mid; //found it! else if ( arr[ mid ] < val ) return binsearch(arr, mid + 1, end, val); else //arr[ mid ] > val return binsearch(arr, start, mid - 1, val); } } ex: 41 62 77 80 85 92 104 211 400 - search for 62 - check index 4 ((0+8)/2) - (0+3)/2 - report found - search for 97 - 97 > 85 - (5+8)/2 = 6 - 97 < 104 - (5+5)/2 = 5 - 97 > 92 Example: Binary Search
  • 4.
    - (5+8)/2 =6 - 97 < 104 - (5+5)/2 = 5 - 97 > 92 - use low and high index values to find that there are no more values to search Consider the sorting problem. That is, given a list of comparable items (say an array of {bf int}s) in arbitrary order, rearrange that list of items so that they are in {it non-decreasing} order. For example, say you have an array of {bf int}s: $langle 38, 27, 43, 3, 9, 82, 10 rangle$. A sorted version of this array would be $langle 3, 9, 10, 27, 38, 43, 82 rangle$. Next, consider an efficient, divide and conquer algorithm that can be used to {it recursively} solve the sorting problem as follows: begin{enumerate} item Divide the unsorted list into two sublists of about half the size. item Divide each of the two sublists recursively until we have list sizes of length $1$, in which case the list itself is returned (after all, a list containing only $1$ element is always considered sorted!). item Merge the two sublists back into one sorted list. end{enumerate} Suppose now that you had the following function available to you: begin{lstlisting}{} void merge(Item arr[], const int& left, const int& right, const int& pivot); end{lstlisting} that combines two {bf sorted} sub-arrays of {tt arr} (i.e., the inclusive intervals [{tt left}, {tt pivot}] and [{tt pivot}$+1$, {tt right}]) to a underline{single} {bf sorted} array. The result of this {it combined}, sorted array is stored back into {tt arr} to form a single, sorted array whose valid elements are contained in the interval [{tt left}, {tt right}]. {tt Item} refers to a type (possibly through use of a {bf typedef}) whose members are comparable (e.g., {bf int}). /* * 'a' is an array of 'Items' whose valid elements are between 'start' and 'end', * inclusively. 'mid' is the position in 'a' in which to divide the array. */ void mergesort(Item a[], const int& start, const int& end, const int& mid) { if ( start >= end ) //the array is either empty or contains a single element. return; //sorting problem already solved. Nothing to do. Example: Mergesort
  • 5.
    if ( start>= end ) //the array is either empty or contains a single element. return; //sorting problem already solved. Nothing to do. //sort the left portion of the array. mergesort(a, start, mid, (start + mid) / 2); //sort the right portion of the array mergesort(a, mid + 1, end, (mid + 1 + end) / 2); //combined the two sorted array portions in a single sorted array. merge(a, start, end, mid); }