Recursion

advertisement
CS340
1
Lecture Objectives
 Learn how to think recursively
 Trace a recursive method
 Prove a recursive method is correct
 Write recursive algorithms and methods for searching
arrays
CS340
2
Recursion
 Recursion can solve many programming problems that are
difficult to solve linearly
 In artificial intelligence, recursion is used to write programs
that
 play games of chess
 prove mathematical theorems
 recognize patterns
 Recursive algorithms can
 compute factorials
 compute a greatest common divisor
 process data structures (strings, arrays, linked lists, etc.)
 search efficiently using a binary search
 find a path through a maze, and more
CS340
Recursive
Thinking
3
CS340
4
Recursive Thinking
• Recursion reduces a problem into one or more simpler
versions of itself
CS340
Recursive Thinking (cont.)
5
CS340
6
Recursive Thinking (cont.)
Recursion of Process Nested Dreams
A child couldn't sleep, so her mother told a story about a little
frog,
who couldn't sleep, so the frog's mother told a story about a
little bear,
who couldn't sleep, so bear's mother told a story about a
little weasel
...who fell asleep.
...and the little bear fell asleep;
...and the little frog fell asleep;
...and the child fell asleep.
CS340
7
Recursive Thinking (cont.)
• Consider searching for a target value in an array
• With elements sorted in increasing order
• Compare the target to the middle element
• If the middle element does not match the target
• search either the elements before the middle
element
• or the elements after the middle element
• Instead of searching n elements, we search n/2 elements
CS340
8
Recursive Thinking (cont.)
Recursive Algorithm to Search an Array
if the array is empty
return -1 as the search result
else if the middle element matches the target
return the subscript of the middle element as the
result
else if the target is less than the middle element
recursively search the array elements before the
middle element and return the result
else
recursively search the array elements after the
middle element and return the result
CS340
9
Steps to Design a Recursive Algorithm
 Base case:
 for a small value of n, it can be solved directly
 Recursive case(s)
 Smaller versions of the same problem
 Algorithmic steps:
 Identify the base case and provide a solution to it
 Reduce the problem to smaller versions of itself
 Move towards the base case using smaller versions
CS340
10
Recursive Algorithm for Finding the
Length of a String
if the string is empty (has no characters)
the length is 0
else
the length is 1 plus the length of the string that
excludes the first character
CS340
11
Recursive Algorithm for Finding the
Length of a String (cont.)
/** Recursive method length
@param str The string
@return The length of the string
*/
public static int length(String str) {
if (str == null || str.equals(""))
return 0;
else
return 1 + length(str.substring(1));
}
CS340
12
Proving that a Recursive Method is
Correct
 Proof by induction
 Prove the theorem base case is true
 Assuming that the theorem is true for n, prove it is true for n+1
 Recursive proof is similar to induction. Verify that
 The base case is recognized and solved correctly
 Each recursive case makes progress towards the base case
 If all smaller problems are solved correctly, then the original
problem also is solved correctly
CS340
Tracing a Recursive Method
• Unwinding the
recursion is the
process of
• returning from recursive
calls
• computing the partial
results
13
CS340
14
Run-Time Stack and Activation Frames
 Java maintains a run-time stack
 Activation frames save information in the run-time stack
 The activation frame contains storage for
 method arguments
 local variables (if any)
 the return address of the instruction that called the method
 Whenever a new method is called (recursive or not), Java
pushes a new activation frame into the run-time stack
CS340
15
Run-Time Stack and Activation Frames
(cont.)
CS340
16
Run-Time Stack and Activation Frames
CS340
17
Recursive Algorithm for Printing String
Characters in Reverse
/** Recursive method printCharsReverse
post: The argument string is displayed in reverse,
one character per line
@param str The string
*/
public static void printCharsReverse(String str) {
if (str == null || str.equals(""))
return;
else {
printCharsReverse(str.substring(1));
System.out.println(str.charAt(0));
}
}
CS340
Recursive Algorithm for Finding
Duplicate characters
/** Recursive method removeDuplicates
post: The word without duplicates
@param word The string
*/
public String removeDuplicates(String word) {
if(word == null || word.length() <= 1)
return word;
else if( word.charAt(0) == word.charAt(1) )
return removeDuplicates(word.substring(1,
word.length()));
else
return word.charAt(0) +
removeDuplicates(word.substring(1,
word.length()));
}
18
CS340
Recursive
Definitions of
Mathematical
Formulas
19
CS340
20
Recursive Definitions of Mathematical
Formulas
• Mathematicians often use recursive definitions of formulas
• Examples include:
• factorials
• powers
• greatest common divisors (gcd)
CS340
Factorial of n: n!
• The factorial of n, or n! is defined as follows:
0! = 1
n! = n x (n -1)! (n > 0)
• The base case: n equal to 0
• The second formula is a recursive definition
21
CS340
Factorial of n: n! (cont.)
 The recursive definition can be expressed by the
following algorithm:
if n equals 0
n! is 1
else
n! = n x (n – 1)!
 The last step can be implemented as:
return n * factorial(n – 1);
22
CS340
Factorial of n: n! (cont.)
public static int factorial(int n) {
if (n == 0)
return 1;
else
return n * factorial(n – 1);
}
23
CS340
24
Infinite Recursion and Stack Overflow
 Call factorial with a negative argument, what will
happen?
StackOverflowException
CS340
25
Recursive Algorithm for Calculating xn
Eclipse example
CS340
26
Recursive Algorithm for Calculating
gcd
• The greatest common divisor (gcd) of two numbers is the
largest integer that divides both numbers
• The gcd of 20 and 15 is 5
• The gcd of 36 and 24 is 12
• The gcd of 38 and 18 is 2
CS340
27
Recursive Algorithm for Calculating
gcd (cont.)
• Given 2 positive integers m and n (m > n)
if n is a divisor of m
gcd(m, n) = n
else
gcd (m, n) = gcd (n, m % n)
CS340
28
Recursive Algorithm for Calculating
gcd (cont.)
/** Recursive gcd method (in RecursiveMethods.java).
pre: m > 0 and n > 0
@param m The larger number
@param n The smaller number
@return Greatest common divisor of m and n
*/
public static double gcd(int m, int n) {
if (m % n == 0)
return n;
else if (m < n)
return gcd(n, m); // Transpose arguments.
else
return gcd(n, m % n);
}
CS340
29
Recursion Versus Iteration
 Similarities between recursion and iteration
 Iteration
 Loop repetition condition determines whether to repeat the loop
body or
 exit from the loop
 Recursion
 The condition usually tests for a base case
 You can always write an iterative solution to a recursion
 But can you always write a recursion for an iteration
problem?
 Which one is best?
CS340
30
Recursion Versus Iteration
• Difference between iteration and recursion is:
• with iteration, each step clearly leads onto the next, like
stepping stones across a river,
• in recursion, each step replicates itself at a smaller scale, so
that all of them combined together eventually solve the
problem.
CS340
31
Iterative factorial Method
/** Iterative factorial method.
pre: n >= 0
@param n The integer whose factorial is being computed
@return n!
*/
public static int factorialIter(int n) {
int result = 1;
for (int k = 1; k <= n; k++)
result = result * k;
return result;
}
CS340
32
Efficiency of Recursion
• Recursive methods often have slower execution times
• Why?
• What about memory and recursion vs iteration?
• Why would we ever prefer recursion?
CS340
33
Fibonacci Numbers
• Fibonacci numbers were invented to model the growth of
a rabbit colony
fib1 = 1
fib2 = 1
fibn = fibn-1 + fibn-2
• 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …
CS340
34
An Exponential Recursive fibonacci
Method
CS340
35
Efficiency of Recursion: Exponential
fibonacci
Inefficient
CS340
36
An O(n) Recursive fibonacci Method
CS340
37
An O(n) Recursive fibonacci Method
(cont.)
 Non-recursive wrapper method:
/** Wrapper method for calculating Fibonacci numbers
(in RecursiveMethods.java).
pre: n >= 1
@param n The position of the desired Fibonacci
number
@return The value of the nth Fibonacci number
*/
public static int fibonacciStart(int n) {
return fibo(1, 0, n);
}
CS340
38
Efficiency of Recursion: O(n)
fibonacci
Efficient
CS340
39
Efficiency of Recursion: O(n)
fibonacci
• Method fibo is an example of tail recursion or last-line
recursion
• Why is it more effective?
CS340
Recursive
Array Search
40
CS340
Recursive Array Search
• Simplest way to search is a linear search
• Start with the first element
• Examine one element at a time
• End with the last
• (n + 1)/2 elements examined in a linear search
• If the target is not in the list, n elements are examined
• What is the complexity?
41
CS340
42
Recursive Array Search (cont.)
• Base cases for recursive search:
• Empty array, target can not be found; result is -1
• First element of the array being searched = target?
• Yes? Then result is the subscript of first element
• No? Then recursive step searches the rest of the array, excluding
the first element
CS340
43
Algorithm for Recursive Linear Array
Search
if the array is empty
the result is –1
else if the first element matches the target
the result is the subscript of the first element
else
search the array excluding the first element and
return the result
CS340
44
Implementation of Recursive Linear
Search
CS340
45
Implementation of Recursive Linear
Search (cont.)
 A non-recursive wrapper method:
/** Wrapper for recursive linear search method
@param items The array being searched
@param target The object being searched for
@return The subscript of target if found;
otherwise -1
*/
public static int linearSearch(Object[] items, Object target)
{
return linearSearch(items, target, 0);
}
CS340
46
Implementation of Recursive Linear
Search (cont.)
CS340
47
Design of a Binary Search Algorithm
 Array has to be sorted
 Base cases
 The array is empty
 Element being examined matches the target
 Compares the middle element for a match with the
target
 Excludes the half of the array within which the target
cannot lie
CS340
48
Binary Search Algorithm (cont.)
if the array is empty
return –1 as the search result
else if the middle element matches the target
return the subscript of the middle element as the
result
else if the target is less than the middle element
recursively search the array elements before the
middle element
and return the result
else
recursively search the array elements after the
middle element and
return the result
49
CS340
Binary Search Algorithm
target
First call
England
China
first = 0
Denmark
England
Greece
middle = 3
Japan
Russia
USA
last = 6
50
CS340
Binary Search Algorithm (cont.)
target
Second call
England
China
Denmark
first = 0
England
last = 2
middle = 1
Greece
Japan
Russia
USA
51
CS340
Binary Search Algorithm (cont.)
target
Third call
England
China
Denmark
England
Greece
first= middle = last = 2
Japan
Russia
USA
52
Efficiency of Binary Search
 An array of 16 would search arrays of length 16, 8, 4, 2,
and 1; 5 probes in the worst case
 16 = 24
 5 = log216 + 1
 A doubled array size would only require 6 probes in the
worst case
 32 = 25
 6 = log232 + 1
 An array with 32,768 elements requires only 16 probes!
(log232768 = 15)
CS340
53
Comparable Interface
• Comparable interface classes must define a
compareTo method
• Method
obj1.compareTo(obj2) returns an integer
• negative: obj1 < obj2
• zero: obj1 == obj2
• positive: obj1 > obj2
54
Implementation of a Binary Search
Algorithm
CS340
Implementation of a Binary Search
Algorithm (cont.)
55
Trace of Binary Search
CS340
56
CS340
57
Testing Binary Search
 You should test arrays with
 an even number of elements
 an odd number of elements
 duplicate elements
 Test each array for the following cases:
 the target is the element at each position of the array
 the target is less than the smallest array element
 the target is greater than the largest array element
 the target is a value between each pair of items in the array
CS340
58
Method Arrays.binarySearch
• Java API class
Arrays contains a binarySearch
method
• If the objects in the array are not comparable or if the array is not
sorted, the results are undefined
• If there are multiple copies of the target value in the array, there is
no guarantee which one will be found
• Throws ClassCastException if the target is not comparable to
the array elements
Download