Title: The Basics of Recursion
1The Basics of Recursion
2Example of a Recursive Algorithm
- Assume you want to find a name in a phone book.
- You could open the book to the middle and if the
name is on that page you are done. - If not, if the name were alphabetically before
the page you were looking at, you could search
the first half of the book. - If it were alphabetically after the current page,
you could search the second half of the book. - Searching half the book is just a smaller version
of searching the entire book so you can use the
same algorithm.
3The Idea of Recursion
- A natural way to design an algorithm often
involves using the same algorithm on one or more
subcases. - If a method definition contains an invocation of
the very method being defined, that invocation is
called a recursive call, or recursive invocation.
4Another Example of Using Recursion
- Suppose the requirement is to take a single
integer and write out the digits of the integer
as words. For example, if the integer input is
223, the algorithm should write out two two
three. - If the integer is a single digit, you can use a
long switch statement to write out the
appropriate word.
5Another Example of Using Recursion (contd)
- This task can be divided into subtasks in many
ways, and not all ways make use of recursion. - One way that does is the following
- Output all but the last digit as words.
- Output the word for the last digit.
- The second statement can be accomplished with our
long switch statement.
6Another Example of Using Recursion (contd)
- If inWords is the name of our method for
outputting the integer in words, we can write out
algorithm as follows - inWords(number with the last digit deleted)
- System.out.print(digitWord(last digit) )
- where digitWord is a method containing the long
switch statement for outputting a single word for
a single digit.
7Another Example of Using Recursion (contd)
- Since number/10 gives the number with the last
digit removed and number10 gives the remainder
which is the last digit, we can rewrite the
algorithm as follows -
- inWords(number/10)
- System.out.print(digitWord(number10) )
8Complete Code for Integer to Words Recursive
Algorithm
- import java.util.public class
RecursionDemo public static void
main(String args)
System.out.println("Enter an integer")
Scanner keyboard new Scanner(System.in)
int number keyboard.nextInt( )
System.out.println("The digits in that number
are") inWords(number)
System.out.println( )
System.out.println("If you add ten to that
number, ") System.out.println("the
digits in the new number are") number
number 10 inWords(number)
System.out.println( ) /
Precondition number gt 0 Action The digits
in number are written out in words. /
public static void inWords(int number)
if (number lt 10)
System.out.print(digitWord(number) " ")
else //number has two or more digits
inWords(number/10)
System.out.print(digitWord(number10) " ")
9Complete Code for Integer to Words Recursive
Algorithm (contd)
- / Precondition 0 lt digit lt 9
Returns the word for the argument digit. /
private static String digitWord(int digit)
String result null switch
(digit) case 0
result "zero" break
case 1 result "one"
break case 2
result "two" break
case 3 result "three"
break case 4
result "four" break
case 5 result
"five" break case
6 result "six"
break case 7
result "seven" break
case 8 result "eight"
break case 9
result "nine" break
default System.out.println(
"Fatal Error.") System.exit(0)
break return
result
10Key to Successful Recursion
- A definition of a method that includes a
recursive invocation of the method itself will
not behave correctly unless some specific
guidelines are followed. - The following rules apply to most cases that
involve recursion - The heart of the method definition is an if-else
statement or some other branching statement that
leads to different cases, depending on some
property of a parameter to the method.
11Key to Successful Recursion (contd)
- One or more of the branches should include a
recursive invocation of the method. These
recursive invocations should, in some way, solve
smaller versions of the task. - One or more branches should include no recursive
invocations. These branches are the stopping
cases (also known as base cases).
12Infinite Recursion
- In order for a recursive method definition to
work correctly and not produce an infinite chain
of recursive calls, there must be one or more
cases that, for certain values of the
parameter(s), will end without producing any
recursive call. - That is, there must be a stopping case.
- When a method invocation leads to infinite
recursion, your program is likely to end with an
error message saying stack overflow.
13Recursive versus Iterative Definitions
- Any method definition that includes a recursive
call can be rewritten so that it accomplishes the
same task without using recursion. - The nonrecursive version typically involves a
loop in place of recursion, and hence is called
an iterative version. - Recursive versions are usually less efficient
than iterative versions, but often make programs
easier to understand.
14Iterative Version of Previous Example
- import java.util.public class
IterativeDemo public static void
main(String args)
System.out.println("Enter an integer")
Scanner keyboard new Scanner(System.in)
int number keyboard.nextInt( )
System.out.println("The digits in that number
are") inWords(number)
System.out.println( )
System.out.println("If you add ten to that
number, ") System.out.println("the
digits in the new number are") number
number 10 inWords(number)
System.out.println( ) /
Precondition number gt 0 Action The digits
in number are written out in words. /
public static void inWords(int number)
int divisor powerOfTen(number) int
next number while (divisor gt 10)
System.out.print(digitWord(next/d
ivisor) " ") next nextdivisor
divisor divisor/10
System.out.print(digitWord(next/divisor) "
")
15Iterative Version of Previous Example (contd)
- / Precondition n gt 0. Returns the
number in the form "one followed by all
zeros that is the same length as n." /
private static int powerOfTen(int n)
int result 1 while(n gt 10)
result result10 n
n/10 return result
16Iterative Version of Previous Example (contd)
- private static String digitWord(int
digit) String result null
switch (digit) case 0
result "zero"
break case 1 result
"one" break case
2 result "two"
break case 3
result "three" break
case 4 result "four"
break case 5
result "five" break
case 6 result "six"
break case 7
result "seven" break
case 8 result "eight"
break case 9
result "nine" break
default
System.out.println("Fatal Error.")
System.exit(0) break
return result
17Example of a Recursive Method that Returns a Value
- Assume the task is to determine the number of
zeros in an integer. - We might write the algorithm as follows
- If n is two or more digits long, then the number
of zero digits in n is (the number of zeroes in n
with the last digit removed) plus an additional
one if the last digit is zero.
18Example of a Recursive Method that Returns a
Value (contd)
- import java.util.public class
RecursionDemo2 public static void
main(String args)
System.out.println("Enter a nonnegative
number") Scanner keyboard new
Scanner(System.in) int number
keyboard.nextInt( ) System.out.println(n
umber " contains "
numberOfZeros(number) " zeros.")
/ Precondition n gt 0 Returns the
number of zero digits in n. / public
static int numberOfZeros(int n) if
(n 0) return 1 else if (n
lt 10)//and not 0 return 0//0 for no
zeros else if (n10 0)
return(numberOfZeros(n/10) 1) else
//n10 ! 0 return(numberOfZeros(n/10)
)