16-2
Chapter Topics
We willcover the following topics in this order:
• 9.1 Recursion
• 9.1.1 Recursive Binary search
• 9.1.2 Towers of Hanoi
• 9.1.3 A Recursive Sorting Algorithm
3.
16-3
Recursion
• A recursivesubroutine (or recursive method)
is one that calls itself, either directly or
indirectly.
• Example:
public static void example()
{
System.out.println("This is a recursive method.");
example();
}
Infinite loop!!
Infinite loop!!
4.
16-4
Controlling Recursion
• Justlike a while or for loop, a recursive method must have some way to control how
many times it repeats so that it eventually stops and not turn into an infinite loop.
• Example:
public static void example(int count)
{
if (count > 0)
{
System.out.println("This is a recursive method.");
example(count -1);
}
}
5.
16-5
Practice
• Write amethod that takes two integers and prints the
numbers from the first integer to the second integer.
– Write it once using a for loop
– Write is using recursion
6.
16-6
How to ImplementRecursion?
• In recursion, you need to first start by defining a base
case. A base case for a recursive algorithm is a case
that is handled directly, rather than by applying the
algorithm recursively.
• Second, define how the problem can be solved in
terms of itself.
7.
16-7
• In mathematics,the factorial of a non-negative integer n, denoted
by n!, is the product of all positive integers less than or equal to n:
• n! = 1 * 2 * 3 * … * n
• For example, 6! is 1 * 2 * 3 * 4 * 5 * 6
• 0! is = 1
• What is the base case?
–The base case is where n is equal to 0:
• How can we rewrite n! in terms of (n-1)!?
Practice: Factorial n!
if n = 0 then factorial(n) = 1
factorial(n) = n × factorial(n – 1)
8.
16-8
private static intfactorial(int n)
{
if (n == 0) return 1; // Base case
else return n * factorial(n - 1);
}
Factorial using Recursion
9.
16-9
Is Recursion aGood Programming
Technique?
• Recursion can be used as a programming technique. It is never the
only way to solve the problem, but sometimes it makes a problem
simpler to implement.
• However, in many cases, recursive algorithms are less efficient than
iterative algorithms (using for and while loops) because they:
keep creating local variables and parameters
need to keep track of the stack trace: a method calling another method needs
to store the address of where control returns after the method finishes.
• This overhead does not happen with loops.
• So why do we still use recursion? Because it saves implementation
time in some cases.
10.
16-10
Example: The FibonacciSeries
• The Fibonacci Sequence is the series of numbers:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
• The next number is found by adding up the two numbers before it:
– the 2 is found by adding the two numbers before it (1+1),
– the 3 is found by adding the two numbers before it (1+2),
– the 5 is (2+3), and so on!
• The Fibonacci series can be defined as:
– Base Case: F(0) = 0 and F(1) = 1
– F(N) = F(N–1) + F(N–2) for N ≥ 2.
fib(7)
fib(7)
11.
16-11
public static intfib(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return fib(n - 1) + fib(n - 2);
}
Example: The Fibonacci Series
12.
16-12
Efficiency of TheFibonacci Series
Algorithm
The computation of fib(6)
calls fib(3) three times.
13.
16-13
The Towers ofHanoi
• The Towers of Hanoi is a mathematical game that uses
3 pegs and a set of disks.
The goal of the game is to move all discs to another peg but
with these rules:
1. Only one disk may be moved at a time.
2. Each move consists of taking the upper disk from one of the stacks
and placing it on top of another stack or on an empty rod.
3. No disk may be placed on top of a disk that is smaller than it.
Video: https://www.youtube.com/watch?v=BalWjeY2O9g
14.
16-14
The Towers ofHanoi
• The problem can be solved both iteratively and recursively.
• Recursively, the following is a procedure for moving a tower of h disks from a
peg A onto a peg C, with B being the remaining third peg:
1. If h > 1, then first use this procedure to move the h − 1 smaller disks from
peg A to peg B.
2. Now the largest disk, i.e. disk h can be moved from peg A to peg C.
3. If h > 1, then again use this procedure to move the h − 1 smaller disks from
peg B to peg C.
4. Base case: if disk count is 0, then done.
void move(int diskCount, int source, int dest, int temp)
{
if (diskCount > 0)
{
move(diskCount - 1, source, temp, dest);
move(diskCount - 1, temp, dest, source);
}
} Start by calling move(diskCount, 1, 3, 2);
15.
16-15
Permutations – Practice
•Permutation is the different ways a set of things can be
arranged.
• Example: Find all permutations of the String “eat”.
"eat"
"eta"
"aet"
"ate"
"tea"
"tae"
Problem: Generate all the permutations of "eat".
First generate all permutations that start with the letter 'e', then
'a' then 't'.
How do we generate the permutations that start with 'e'?
We need to know the permutations of the substring "at". But that’s the same problem—
to generate all permutations— with a simpler input
Prepend the letter 'e' to all the permutations you found of 'at'.
Do the same for 'a' and 't'.
Provide a special case for the simplest strings.
The simplest string is the empty string, which has a single permutation—itself.
16.
public static ArrayList<String>permutations(String word)
{
ArrayList<String> result = new ArrayList<String>();
if (word.length() == 1)//Base case: empty string only has itself as permutation
{
result.add(word);
return result;
}
else
{
// Loop through all character positions
for (int i = 0; i < word.length(); i++)
{
// Form a shorter word by removing the ith character
shorter = word.substring(0, i) + word.substring(i + 1);
// Generate all permutations of the simpler word
ArrayList<String> shorterPermutations = permutations(shorter);
//Add removed char to the front of each permutation of the simpler word
for (String s : shorterPermutations)
{
result.add(word.charAt(i) + s);
}
}
// Return all permutations
return result;
}
}
1-16
17.
16-17
• Write amethod product(int x, int y) which returns the product of multiplying x * y but
doing it recursively. Recall that multiplication can be implemented as repeated addition.
For example, 4 * 7 is the same as adding 7, 4 times: 7 + 7 + 7 + 7.
• Write a main method that asks for two numbers, and returns their product by calling the
product method.
Compile and test your code in NetBeans and then on Hackerrank at
https://www.hackerrank.com/csc128-part-5-classwork then choose CSC128-Classwork-
Part-5-1
Submit your .java file and a screenshot of passing all test cases on Hackerrank.
CW Part-5-1: Simple Recursion
18.
16-18
Direct and IndirectRecursion
• When recursive methods directly call themselves it is known as
direct recursion.
• Indirect recursion (mutual recursion) is when method A calls
method B, which in turn calls method A.
• There can even be several methods involved in the recursion.
– Example, method A could call method B, which could call method C,
which calls method A.
• Care must be used in indirect recursion to ensure that the proper
base cases and return values are handled. f1() {
//do something
f2();
//do something
}
f2() {
//do something
f1();
//do something
}
19.
16-19
Indirect Recursion Examples
booleaneven( int number )
{
if( number == 0 )
return true;
else return odd(abs(number)-
1)
}
boolean odd( int number )
{
if( number == 0 )
return false;
else
return even(abs(number)-1);
}
• Determine whether a
number is even or odd
by testing the number
before it (1 less).
• Inefficient!!
16-21
Indirect Recursion Examples
•An expression can broken down into a
sequence of terms, separated by + or
- .
• Each term is broken down into a
sequence of factors, separated by *
or / .
• Each factor is either a parenthesized
expression or a number.
• The syntax trees represent which
operations should be carried out first.
22.
15-22
• Write amethod sumArray that sums up the elements in an array.
• It might be useful to write a helper method that takes as input the range of elements to add
Helper Methods: Summing Array Elements
public static sumArray(int[] array)
{
return rangeSum(array, 0, array.length -1);
}
public static int rangeSum(int[] array,
int start, int end)
{
if (start > end)
return 0;
else
return array[start]
+ rangeSum(array, start + 1, end);
}
23.
CW Part-5-2: MoreRecursion
• Write a recursive method smallestNumber which takes an
ArrayList of Integers as input and returns the smallest number in the
array. You can use a helper method if needed.
• Write a main method that asks the user for a series of numbers, until
the user enters a period. Main should create an ArrayList of these
Integers and call smallestNumber to find the smallest number and
print it.
Compile and test your code in NetBeans and then on Hackerrank at
https://www.hackerrank.com/csc128-part-5-classwork then choose
CSC128-Classwork-Part-5-2
Submit your .java file and a screenshot of passing all test cases
on Hackerrank.
1-23
24.
Programming Assignment (50Points)
• Write a recursive method, reverseString, that accepts a String and returns the
String reversed.
• Write a recursive method, reverseArrayList, that accepts an ArrayList of Strings
and returns an ArrayList in reserve order of the input ArrayList.
• Write a main method that asks the user for a series of Strings, until the user enters
“Done” and puts them in an ArrayList. Main should make use to
reverseArrayList and reverseString to reverse each String in the ArrayList and
then reverse the ArrayList.
Compile and test your code in NetBeans and then on Hackerrank at
https://www.hackerrank.com/contests/csc128-programmingassignments then choose
CSC128-Part-5-PA
Submit your .java file and a screenshot of passing all test cases on Hackerrank.
1-24
25.
Acknowledgment
"Java II –Part 5 – Recursion" by Ibtsam
Mahfouz, Manchester Community
College is licensed under CC BY-NC-SA
4.0 / A derivative from the original work