Notes 12: Recursion

Download Report

Transcript Notes 12: Recursion

Recursion
Lecture Objectives
• Learn about recursive definitions
• Explore the base case and the general case
of a recursive definition
• Learn about recursive algorithms
Lecture Objectives (Cont’d)
• Learn about recursive methods
• Become aware of direct and indirect
recursion
• Explore how to use recursive methods to
implement recursive algorithms
Recursive Definitions
• Recursion
 Process of solving a problem by reducing it to smaller
versions of itself
• Recursive definition
 Definition in which a problem is expressed in terms of a
smaller version of itself
 Has one or more base cases
Recursive Definitions (Cont’d)
0!
n!
3!
2!
1!
=
=
=
=
=
1 (By Definition!)
n x (n – 1) ! If n > 0
3 x 2!
2 x 1!
1 x 0!
0! =
1 (Base Case!)
1! =
2! =
3! =
1 x 0!
2 x 1!
3 x 2!
= 1x1=1
= 2x1=2
= 3x2=6
Recursive Definitions (Cont’d)
• Recursive algorithm
 Algorithm that finds the solution to a given problem by
reducing the problem to smaller versions of itself
 Has one or more base cases
 Implemented using recursive methods
• Recursive method
 Method that calls itself
• Base case
 Case in recursive definition in which the solution is
obtained directly
 Stops the recursion
Recursive Definitions (Cont’d)
• General solution
 Breaks problem into smaller versions of itself
• General case
 Case in recursive definition in which a smaller
version of itself is called
 Must eventually be reduced to a base case
Recursive Definitions (Cont’d)
• Directly recursive: a method that calls itself
• Indirectly recursive: a method that calls
another method and eventually results in the
original method call
• Tail recursive method: recursive method in
which the last statement executed is the
recursive call
• Infinite recursion: the case where every
recursive call results in another recursive call
Tracing a Recursive Method
• Recursive method
 Logically, you can think of a recursive method having
unlimited copies of itself
 Every recursive call has its own
• Code
• Set of parameters
• Set of local variables
Tracing a Recursive Method (Cont’d)
• After completing a recursive call
 Control goes back to the calling environment
 Recursive call must execute completely before control
goes back to previous call
 Execution in previous call begins from point
immediately following recursive call
Designing Recursive Methods
• Understand problem requirements
• Determine limiting conditions
• Identify base cases
Designing Recursive Methods (Cont’d)
• Provide direct solution to each base case
• Identify general case(s)
• Provide solutions to general cases in terms
of smaller versions of general cases
Recursive Factorial Method
public static int fact(int num) {
if (num = = 0)
return 1;
else
return num * fact(num – 1);
}
Recursive Factorial Method (Cont’d)
Figure 1: Execution path of fact(4)
Largest Value in Array
Figure 2: Array with six elements
Largest Value in Array (Cont’d)
•
•
•
•
if the size of the list is 1
- the largest element in the list is the only element in the
array
else
- to find the largest element in list[a]...list[b]
a. find the largest element in list[a +
1]...list[b]
and call it max
b. compare list[a] and max
if (list[a] >= max)
the largest element in list[a]...list[b] is
list[a]
else
the largest element in list[a]...list[b] is max
Largest Value in Array (Cont’d)
public static int largest(int[] list, int lowerIndex, int upperIndex) {
int max;
if (lowerIndex == upperIndex)
return list[lowerIndex];
else {
max = largest(list, lowerIndex + 1,
upperIndex);
if (list[lowerIndex] >= max)
return list[lowerIndex];
else
return max;
}
}
Execution of largest(list, 0, 3)
Figure 3: Array with four elements
System.out.println(largest(list, 0, 3));
Execution of largest(list, 0, 3) (Cont’d)
Figure 4: Execution of largest(list, 0, 3)
Recursive Fibonacci
Recursive Fibonacci (Cont’d)
public static int rFibNum(int a, int b, int n) {
if (n == 1)
return a;
else if (n == 2)
return b;
else
return rFibNum(a, b, n -1) +
rFibNum(a, b, n - 2);
}
Recursive Fibonacci (Cont’d)
Figure 5: Execution of rFibNum(2, 3, 5)
Recursion and the Method Call Stack
• Method call stack used to keep track of method
calls and local variables within a method call
• Just as with nonrecursive programming, recursive
method calls are placed at the top of the method
call stack
• As recursive method calls return, their activation
records are popped off the stack and the previous
recursive calls continue executing
• Current method executing is always method
whose activation record is at top of stack
Recursion and the Method Call Stack (Cont’d)
Figure 6: Method calls on the program execution stack
Towers of Hanoi Problem with Three
Disks
Figure 7: Tower of Hanoi Problem with three disks
Towers of Hanoi: Three Disk Solution
Figure 8: Tower of Hanoi Problem with three disks – Solution 1
Towers of Hanoi: Three Disk Solution (Cont’d)
Figure 9: Tower of Hanoi Problem with three disks – Solution 2
Towers of Hanoi: Recursive Algorithm
public static void moveDisks(int count, int needle1, int needle3, int needle2) {
if (count > 0) {
moveDisks(count - 1, needle1,
needle2, needle3);
System.out.println("Move disk " + count
+ " from needle "
+ needle1 + " to needle "
+ needle3 + ". ");
moveDisks(count - 1, needle2,
needle3, needle1);
}
}
Recursion or Iteration?
• Two ways to solve particular problem
 Iteration
 Recursion
• Both iteration and recursion use a control
statement
 Iteration uses a repetition statement
 Recursion uses a selection statement
Recursion or Iteration? (Cont’d)
• Iteration and recursion both involve a termination test
 Iteration terminates when the loop-continuation condition fails
 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
Programming Example: Decimal to Binary
public static void decToBin(int num, int base) {
if (num > 0) {
decToBin(num / base, base);
System.out.print(num % base);
}
}
Execution of decToBin(13, 2)
Figure 10: Execution of decToBin(13, 2)
Sierpinski Gaskets of Various Orders
Figure 11: Sierpinski Gaskets
Programming Example: Sierpinski Gasket
• Input: non-negative integer indicating level of
Sierpinski gasket
• Output: triangle shape displaying a
Sierpinski gasket of the given order
• Solution includes:
 Recursive method drawSierpinski
 Method to find midpoint of two points
Programming Example: Sierpinski Gasket (Cont’d)
private void drawSierpinski(Graphics g, int lev,Point p1, Point p2, Point p3) {
Point midP1P2;
Point midP2P3;
Point midP3P1;
if (lev > 0) {
g.drawLine(p1.x, p1.y, p2.x, p2.y);
g.drawLine(p2.x, p2.y, p3.x, p3.y);
g.drawLine(p3.x, p3.y, p1.x, p1.y);
midP1P2 = midPoint(p1, p2);
midP2P3 = midPoint(p2, p3);
midP3P1 = midPoint(p3, p1);
drawSierpinski(g, lev - 1, p1, midP1P2,midP3P1);
drawSierpinski(g, lev - 1, p2, midP2P3, midP1P2);
drawSierpinski(g, lev - 1, p3, midP3P1, midP2P3);
}
}
Programming Example: Sierpinski Gasket (Cont’d)
Figure 12: Sierpinski Gaskets: Recursion depth of 3
Lecture Summary
• Recursive definitions
• Recursive algorithms
• Recursive methods
• Base cases
• General cases
Lecture Summary (Cont’d)
• Tracing recursive methods
• Designing recursive methods
• Varieties of recursive methods
• Recursion vs. Iteration
• Various recursive functions explored