BBIT 1201 5/22/2023
Introduction
• Recursion:
0! = 1 (By Definition!)
– Process of solving a problem by n! = n x (n – 1) ! If n > 0
reducing it to smaller versions of itself 3! = 3 x 2!
• Recursive algorithm: 2! = 2 x 1!
Recursion – Algorithm that finds the solution to a
given problem by reducing the problem
1! = 1 x 0!
to smaller versions of itself 0! = 1 (Base Case!)
– Has one or more base cases 1! = 1 x 0! = 1x1=1
– Implemented using recursive methods 2! = 2 x 1! = 2x1=2
3! = 3 x 2! = 3x2=6
Definitions Definitions
• Recursive method: • Directly recursive: a method that calls itself
– Method that calls itself • Indirectly recursive: a method that calls another method and eventually results in
• Base case: the original method call. Method A calls method B, which in turn calls method A.
– Case in recursive definition in which the solution is obtained directly
– Stops the recursion
• Infinite recursion:
– Case where every recursive call results in another recursive call.
• General case:
– It is caused by either omitting base case or writing recursion step that does not converge on base
– Case in recursive definition in which a smaller version of itself is called case.
– Must eventually be reduced to a base case – Memory may get exhausted.
Tracing a Recursive Method Designing Recursive Methods
• Recursive method: • Understand problem
– Logically, you can think of a recursive method having unlimited copies of itself 0! = 1 (By Definition!)
requirements n! = n x (n – 1) ! If n > 0
– Every recursive call has its own set of local variables.
• Identify base cases 3! = 3 x 2!
• After completing a recursive call: 2! = 2 x 1!
• Provide direct solution to each 1! = 1 x 0!
– Control goes back to the calling environment
base case
– Each recursive call must execute completely before control goes back to previous call 0! = 1 (Base Case!)
– Execution in previous call begins from point immediately following recursive call
• Identify general case(s)
• Provide solutions to general cases 1! = 1 x 0! = 1x1=1
2! = 2 x 1! = 2x1=2
in terms of smaller versions of 3! = 3 x 2! = 3x2=6
general cases
1
BBIT 1201 5/22/2023
Example Using Recursion: Factorial of a Number Factorial of a Number Using Iteration
import java.util.Scanner;
public class Factorial
• Factorial of n, or n! is the product: {
0! = 1 (By Definition!) public static void main(String[] args)
n · (n – 1) · (n – 2) · … · 1 n! = n x (n – 1) ! If n > 0 {
• With 1! equal to 1 and 0! defined to be 1. 3! = 3 x 2! Scanner scanner = new Scanner(System.in);
2! = 2 x 1! System.out.print("Enter the number whose factorial is to be found: ");
• Can be solved recursively or iteratively 1! = 1 x 0!
int n = scanner.nextInt();
int result = factorial(n);
• Recursive solution uses following System.out.println("The factorial of " + n + " is " + result);
0! = 1 (Base Case!)
relationship: n! = n · (n – 1)! }
public static int factorial(int n)
1! = 1 x 0! = 1x1=1 {
2! = 2 x 1! = 2x1=2 int result = 1;
3! = 3 x 2! = 3x2=6 for (int i = 1; i <= n; i++)
{
result = result * i;
}
return result;
}
7 }
9 10
Factorial of a Number Using Iteration Factorial of a Number Using Iteration
1 // Fig. 15.10: FactorialCalculator.java
2 // Iterative factorial method. 1 // Fig. 15.11: FactorialTest.java
3 2 // Testing the iterative factorial method.
4 public class FactorialCalculator 3
5 {
4 public class FactorialTest
6 // recursive declaration of method factorial
5 {
7 public long factorial( long number )
6 // calculate factorials of 0-10
8 {
9 long result = 1; 7 public static void main( String args[] )
10 8 {
11 // iterative declaration of method factorial 9 FactorialCalculator factorialCalculator = new FactorialCalculator();
12 for ( long i = number; i >= 1; i-- ) 10 factorialCalculator.displayFactorials();
13 result *= i; 11 } // end main
14
15 return result;
Iterative solution uses counter-controlled 12 } // end class FactorialTest
16 } // end method factorial repetition 0! = 1
1! = 1
17 2! = 2
3! = 6
18 // output factorials for values 0-10 4! = 24
19 public void displayFactorials() 5! = 120
6! = 720
20 { 7! = 5040
21 // calculate the factorials of 0 through 10 8! = 40320
9! = 362880
22 for ( int counter = 0; counter <= 10; counter++ ) 10! = 3628800
23 System.out.printf( "%d! = %d\n", counter, factorial( counter ) );
24 } // end method displayFactorials
25 } // end class FactorialCalculator
Factorial of a Number Using Recursion Factorial of a Number Using Recursion
The method is first
called from the main First call of the method
method of the n=4
FactorialDemo class. Return value: 24
Second call of the method
n=3
Return value: 6
Third call of the method
n=2
Return value: 2
Fourth call of the method
n=1
Return value: 1
Fifth call of the method
n=0
Return value: 1
15-11 12
2
BBIT 1201 5/22/2023
14
Factorial of a Number Using Recursion 1
2
// Fig. 15.4: FactorialTest.java
// Testing the recursive factorial method.
3
4 public class FactorialTest
1 // Fig. 15.3: FactorialCalculator.java 13
5 {
2 // Recursive factorial method.
Base case returns 1 6 // calculate factorials of 0-10
3
4 public class FactorialCalculator 7 public static void main( String args[] )
5 { 8 {
6 9 FactorialCalculator factorialCalculator = new FactorialCalculator();
// recursive method factorial
Recursion step breaks problem into two
7 public long factorial( long number ) 10 factorialCalculator.displayFactorials();
8 { parts: one the method knows how to do, 11 } // end main
9 if ( number <= 1 ) // test for base case one the method does not 12 } // end class FactorialTest Calculate and display
10 return 1; // base cases: 0! = 1 and 1! = 1
0! = 1
factorials
11 else // recursion step
1! = 1
12 return number * factorial( number - 1 ); 2! = 2
13 } // end method factorial Recursive call: Portion method does not know 3! = 6
14 4! = 24
how to do; smaller version of original problem 5! = 120
15 // output factorials for values 0-10 6! = 720
16 public void displayFactorials() 7! = 5040
17 { Portion method knows how to do 8! = 40320
9! = 362880
18 // calculate the factorials of 0 through 10 10! = 3628800
19 for ( int counter = 0; counter <= 10; counter++ )
20 System.out.printf( "%d! = %d\n", counter, factorial( counter ) );
21 } // end method displayFactorials
22 } // end class FactorialCalculator
Original call to recursive
method
Power of a Number (xy ) Using Iteration Power of a Number Using Recursion
// Returns base ^ exponent.
int static power(int x, int y) // Precondition: exponent >= 0
{ public static int pow(int base, int exponent) {
if (exponent == 0) {
int pow = 1; // base case; any number to 0th power is 1
return 1;
for (int i = 1; i <= y; i++) } else {
pow *= x; // recursive case: x^y = x * x^(y-1)
return base * pow(base, exponent - 1);
return pow; }
}
}
Power of a Number Using: Recursion An Power of a Number Using Recursion –
optimization Optimized Version
• Notice the following mathematical property: // Returns base ^ exponent.
// Precondition: exponent >= 0
312 = 531441 = 96 public static int pow(int base, int exponent) {
= (32)6 if (exponent == 0) {
531441 = (92)3 // base case; any number to 0th power is 1
return 1;
= ((32)2)3
} else if (exponent % 2 == 0) {
// recursive case 1: x^y = (x^2)^(y/2)
– When does this "trick" work?
return pow(base * base, exponent / 2);
– How can we incorporate this optimization into our pow method? } else {
– What is the benefit of this trick if the method already works? // recursive case 2: x^y = x * x^(y-1)
return base * pow(base, exponent - 1);
}
}
3
BBIT 1201 5/22/2023
Fibonacci Series Using Iteration Fibonacci Series Using Recursion
public class MyFibonacci {
1 // Fig. 15.5: FibonacciCalculator.java
2 // Recursive fibonacci method. 20
public static void main(String a[]) 3
{ 4 public class FibonacciCalculator
5 {
int febCount = 15; 6 // recursive declaration of method fibonacci
Two base cases
int[] feb = new int[febCount]; 7 public long fibonacci( long number )
8 {
feb[0] = 0; 9
feb[1] = 1;
if ( ( number == 0 ) || ( number == 1 ) ) // base cases
Two recursive calls
10 return number;
11 else // recursion step
12 return fibonacci( number - 1 ) + fibonacci( number - 2 );
for(int i=2; i < febCount; i++) 13 } // end method fibonacci
{ 14
15 public void displayFibonacci()
feb[i] = feb[i-1] + feb[i-2]; 16 {
} 17 for ( int counter = 0; counter <= 10; counter++ )
18 System.out.printf( "Fibonacci of %d is: %d\n", counter,
19 fibonacci( counter ) );
for(int i=0; i< febCount; i++){ 20 } // end method displayFibonacci
System.out.print(feb[i] + " "); 21 } // end class FibonacciCalculator
} Original call to recursive method
}
}
Fibonacci Series Using Recursion Fibonacci Series Using Recursion
1 // Fig. 15.6: FibonacciTest.java
22
2 // Testing the recursive fibonacci method.
3
4 public class FibonacciTest
5 {
6 public static void main( String args[] )
7 {
8 Calculate and display Fibonacci
FibonacciCalculator fibonacciCalculator = new FibonacciCalculator();
9 fibonacciCalculator.displayFibonacci(); values
10 } // end main
11 } // end class FibonacciTest
Fibonacci of 0 is: 0
Fibonacci of 1 is: 1
Fibonacci of 2 is: 1
Fibonacci of 3 is: 2
Fibonacci of 4 is: 3
Fibonacci of 5 is: 5
Fibonacci of 6 is: 8
Fibonacci of 7 is: 13
Fig. 15.7 | Set of recursive calls for fibonacci( 3 ). Fibonacci
Fibonacci
Fibonacci
of
of
of
8 is: 21
9 is: 34
10 is: 55
21
Common Programming Errors in Recursion Recursion vs. Iteration
• Either omitting the base case or writing the recursion step incorrectly so that it does • Any problem that can be solved recursively can be solved iteratively.
not converge on the base case can cause a logic error known as infinite recursion, • Both iteration and recursion use a control statement:
where recursive calls are continuously made until memory has been exhausted. – Iteration uses a repetition statement
• This error is analogous to the problem of an infinite loop in an iterative (non- – Recursion uses a selection statement
recursive) solution. • Iteration and recursion both involve a termination test:
• Accidentally having a non-recursive method call itself either directly or indirectly – Iteration terminates when the loop-continuation condition fails
through another method can cause infinite recursion. – Recursion terminates when a base case is reached
• Recursion can be expensive in terms of processor time and memory space, but
usually provides a more intuitive solution.
23 24
4
BBIT 1201 5/22/2023
Software Engineering Observation
• Any problem that can be solved recursively can also be solved iteratively
(nonrecursively).
• A recursive approach is normally preferred over an iterative approach when the
recursive approach more naturally mirrors the problem and results in a program that
is easier to understand and debug.
• A recursive approach can often be implemented with fewer lines of code.
• Another reason to choose a recursive approach is that an iterative one might not be
apparent.
25