Title: A1261432808AswvD
1Recursion
- When confronted with a new problem there are two
questions you should ask - Â
- 1. Is this problem like, or a special case of, a
problem that I already know how to solve? - 2.Is this a problem of size n in one of its
variables that I could solve if I knew the
solution to an instance of the same problem (or
instances of all such problems) of size less than
n? - Â
2Recursion
When the answer to the second question is yes,
you will employ recursion.
There are three steps in formulating a recursive
solution to a problem.
- Formulate the solution (to a problem of size n)
in terms of the solution to the same problem of
size less than n.
- Determine a base case (at n 0) where the
solution to the problem is trivial.
- Terminate recursion when this base case value
is reached.
Recursion rewards procrastination by
formulating the solution of a problem as a
sequence of solutions to similar problems, and
postponing the actual solution of any of these
problems until they are trivial.
3Recursion Contents of Presentation
- Recursion as a problem solving technique
- Towers of Hanoi An example of a recursive
approach to problem solving. - Recursive Algorithms The Good, the Bad, and the
Ugly! - a) The Good Raising a base to a power.
- b) The Bad Calculating N Factorial.
- c) The Ugly The Fibonacci Sequence
- Binary Search
- Recursively Defined Grammars Finding
Palindromes
4Example Towers of Hanoi puzzle
In this puzzle, the player begins with n disks of
decreasing diameter placed one on top of the
other on one of three pegs of the game board.
The player must move the disks from peg to peg,
using each of the three pegs, until the entire
tower is moved from the starting peg to one of
the others. The only rule governing the movement
of the disks is that in each move a disk of
larger diameter must never be placed on top of
one of smaller diameter
5Towers of Hanoi Puzzle
6Towers of Hanoi Puzzle
7Towers of Hanoi Puzzle
8Towers of Hanoi Puzzle
9Towers of Hanoi Puzzle
10Towers of Hanoi Puzzle
11Towers of Hanoi Puzzle
12Towers of Hanoi Puzzle
A solution to the problem of moving a tower of
size n from the source peg to the destination peg
using a spare peg is found by moving a tower of
size n 1 from the source peg to the spare peg,
moving the bottom disk from the source peg to the
destination peg, and finally moving a tower of
size n 1 from the spare peg to the destination
peg.
13Class TowersOfHanoi -- header file
public class TowersOfHanoi private int
num_disks private int source, spare,
dest //pegs public TowersOfHanoi (int
n_disks) //see next slide
//pre-condition n_disks gt 0 //exception
error message sent and program terminates
public void moveTower(int disks, int from_peg,
int to_peg, int use_peg) public void
moveDisk(int num, int from_peg, int to_peg)
14Class TowersOfHanoi -- implementation
Class Constructor
public TowersOfHanoi(int n_disks) if ( n_disks
lt 1) System.err.println( error must
start with 1 or more disks in a tower
exit(1) num_disks n_disks source 1
spare 2 dest 3 moveTower(num_disks,
source, dest, spare)
15Class TowersOfHanoi -- implementation
moveTower
public void moveTower(int disks, int from_peg,
int to_peg, int use_peg) if (disks 1)
moveDisk(disks, from_peg, to_peg) else
moveTower(disks 1, from_peg, use_peg,
to_peg) moveDisk(disks, from_peg,
to_peg) moveTower(disks 1, use_peg,
to_peg, from_peg)
16Class TowersOfHanoi -- implementation
moveDisk
public void moveDisk(int num, int from_peg, int
to_peg) System.out.print( moving disk
number num from peg)
System.out.println(from_peg to peg
to_peg )
17Illustration of moveTower operation
public void moveTower(int disks, int from_peg,
int to_peg, int use_peg) if (disks
1) moveDisk(disks, from_peg, to_peg)
else moveTower(disks-1, from_peg, use_peg,
to_peg) moveDisk(disks, from_peg,
to_peg) moveTower(disks-1, use_peg, to_peg,
from_peg)
screen
1 1 3
2 1 2
3
1 3 2
3 1 3
1 2 1
2 2 3
1 1 3
Calls to moveTower
Stack of act. Recs.
18Recursively Defined Functions
The Good, the bad, and the ugly
Exponentiation --The Good
 1 if n 0 1/ power(b, n) if n lt
0 power (b, n) ? b power (b, n-1) if n gt 0
and odd power(b, n/2) power(b,n/2) if
n gt 0 and even
19Recursive power function
The recursive algorithm completes after at most
2lg(n) calls
public double power (double b, int n) //start
all recursive functions with a test for the base
case //test to terminate recursion) if ( n
0) return 1 if (n lt 0) return 1/power(b,
-n) if ((n 2) 1) return b power(b,
n-1) else // n even and positive double
temp power(b, n/2) return temp temp
20Recursively Defined Functions
The bad
1 if n 0 n! ? n (n 1)
! for all n gt 0 Â Figure 2. The factorial
function Â
21Recursively Defined Functions
The Factorial Function
public long factorial (int n) //precondition n
gt 0 if (n lt 0) System.out.println(
error factorial function requires
non-negative argument\n
exit(1) if (n 0) return
1 else return n factorial (n 1)
Requires n time (and space) consuming function
calls
22Recursively Defined Functions
Tail Recursion
The recursive factorial algorithm uses recursion
as the last statement in the function, only to
set the parameters for the next round of
processing. This is better done by iteration!
Consider this example.
public void reverse_write(const char A, int
size) if (size gt 0) System.out.print(
Asize 1) reverse_write (A, size 1)
23Recursively Defined Functions
Eliminating Tail Recusion
public void iterative_reverse_write(const char A
, int size) while (size gt 0)
System.out.println( Asize 1) size--
24Recursively Defined Functions
Non-recursive factorial function
public long iterative_factorial (int n)
//precondition n gt 0 if (n lt 0)
System.out.println( error factorial function
requires non- negative argument)
exit(1) long prod n while ( n gt 1)
n-- prod n return
prod
n iterations, but much faster and uses less
memory than n recursive calls!
25Recursively Defined Functions
The ugly the fibonacci function
0 if n 0 fibon (n) ? 1 if n
1 finbon(n-1) fibon(n-2) if n gt 1
26Recursive fibonacci function
public long fibon (long int n)
//precondition n gt 0 //exception if n
send an error message and terminate if ( n lt
0 ) System.out.println( error fibonacci
numbers not defined over negative
numbers) exit (1) if (n
0) return 0 //base cases if (n 1) return
1 return fibon(n-1) fibon(n-2)
27The fibonacci function
The run-time behavior of this recursive algorithm
becomes exponential because the algorithm is
senile. It forgets the value it obtained on
a previous call and has to (recursively)
recalculate the same value again.
8
fibon(6)
5
3
fibon(5)
fibon(4)
3
2
2
1
fibon(3)
fibon(4)
fibon(3)
fibon(2)
1
1
1
1
2
1
1
0
fibon(2)
fibon(1)
fibon(2)
fibon(1)
fibon(3)
fibon(2)
fibon(1)
fibon(0)
0
1
1
1
0
1
0
1
fibon(2)
fibon(1)
fibon(1)
fibon(0)
fibon(1)
fibon(0)
fibon(1)
fibon((0)
1
0
fibon(1)
fibon(0)
28An iterative fibonacci function
public long iterative_fibon(long int n)
//precondition n gt 0 //exception if n
send an error message and terminate if ( n
lt 0 ) System.out.println( error fibonacci
numbers not defined over negative
numbers) exit (1) if (n
0) return 0 //base cases if (n 1) return
1 long int term1 1, term2 0, hold
for (int i 2 i lt n i) hold
term1 term1 term2 term2 hold
return term1
Requires only 2 memory locations and n
iterations!
29Divide and Conquer
Binary Search
public int binarySearch(int A, int first,
int last, int key) .. //preconditions li
st A is ordered in increasing order (not
checked) // last gt first (sub-list is
not empty) //post conditions list A is
unchanged, if key occurs in the list the index
// of (one of) the location where it
occurs is returned, else // a dummy
value of 1 is returned //exception if
first gt last send error message and terminate
30Initial State of List A
31State of List A during the first call to
binary_search
32State of List A during the third call to
binary_search
33public int binarySearch(int A, int first,
int last, int key) //check for
exception if (first gt last)
System.out.println( error list to be
searched is empty) exit(1)
//check for termination of recursion if
((last first) 1) if (Afirst key)
return first else return 1
int med (first last) / 2 //integer
division if (key lt Amed ) binarySearch
(A, first, med, key) else binarySearch
(A, med, last, key)
34Recursively Defined Grammars
Palindrome
L w w is a string of alphabetic characters
that is the same read backwards or
forwards  and the BNF grammar G
is  ltpalindromegt ltempty_stringgt
ltalphabeticgt a ltpalindromegt a lt Z
ltpalindromegt Z ltalphabeticgt a z
A Z ltempty_stringgt
35Test for a palindrome
public boolean isPalindrome(String s)
if ( s NULL) return TRUE if
(s.length 1) return TRUE int len
s.length return boolean (s.charAt(0)
s.charAt(len-1)) isPalindrome(s.substring(
1,len-2))