This lab is devoted to recursion.
We start with the classical example of a recursive function for computing n! based on the formula n! = n * (n-1)!:
int n = factorial(n);
. . .
. . .
public static int factorial(n)
{
if (n==1) return(1); // termination condition
return (n* factorial(n-1)); // recursive call
}
|
String s = "abcdefgh";
writeString(s, 0); // function call
. . .
. . .
// prints string s starting with character at index i
public static void writeString(String s, int i)
{
if (i == s.length()) return(); // termination condition
Output(s.charAt(i)); // print the i-th char of s
writeString(s, i+1); // recursive call
}
|
Consider Fibonacci sequence of integer numbers. The first two numbers in that sequence are 1 and 1. Every other number is the sum of the two previous ones. In other terms, Fibonacci sequence can be defined by a recursion:
f0 = f1 = 1
fn = fn-1 + fn-2 for n ≥ 2
A high-level recursive routine for generating such sequence is straightforward.
public static int fib(int n)
{
if (n < 2) return(1); // termination condition
return fib(n-1) + fib(n-2); // recursive call
}
|
It turns out that the number of recursive calls in the previous implementation grows exponentially. This is what generally happens if one have multiple (more than 1) recursive calls in a recursive function.
To improve the situation, we store a computed for the first time value of fib(m) in a local array. Then, first check if the value fin(m) was computed before, and in this case take it from the table. This idea can be implemented as it is shown in the following Java code:
public class Fibonacci
{
private static int[] fibNumbers;
public static void main(String[] args)
{
int n = Integer.parseInt(args[0]); // get n from the command line
fibNumbers = new int[n]; // create and initialize array for
for (int i=0; i<n; i++) // computed Fibonacci numbers
fibNumbers[i] = 0;
System.out.print("Applying the memorized recursion: fib(" + n + ")=");
int f = fib(n); // apply the accelerated method
System.out.println(f);
}
// memorized recursive implementation of the same sequence
public static int fib(int n)
{
if (n <= 1) return(1); // termination condition
int a, b;
if (fibNumbers[n-1] != 0) // if the (n-1)-th Fib. number
a = fibNumbers[n-1]; // is already computed, take it from the table
else
{ // otherwise apply the recursion to compute it
a = fib(n-1); // and store in variable a
fibNumbers[n-1] = a;
}
if (fibNumbers[n-2] != 0) // same approach for the (n-2)-th
b = fibNumbers[n-2]; // number
else
{
b = fib(n-2); // store it in b
fibNumbers[n-2] = b;
}
return(a+b);
}
}
|
javac Fibonacci.java
java Fibonacci 40