Title: Chapter 19 : Recursion
1Chapter 19 Recursion
2Objectives
- After studying this chapter you should understand
the following - recursion, and the relationship between recursive
and iterative algorithms - the design of the quick sort algorithm
- indirect recursion
- backtracking and the class of problems it solves
- object recursion and its class structure.
3Objectives
- Also, you should be able to
- write simple recursive algorithms
- use backtracking in the solution to problems
- structure class definitions to use object
recursion.
4Iterative Algorithms
- Algorithm
- Specifies a step in the solution process.
- Step is iterated.
- After each iteration, we are closer to solution.
- Solution is reached after a finite number of
iterations.
5Recursion
- Algorithms
- Solve a trivial, basic case of problem,
- Solution to general case is reduced to one that
is a step closer to basic case.
6Iteration v.s. Recursion
- Reducing general case to a easier case roughly
corresponds to a single iterative step. - Reaching base case stops recursion as exit
condition stops iteration.
7Iteration v.s. Recursion
- In an iterative solution
- step toward solution until while condition is
false. - explicitly drive repetition with a loop.
- In a recursive solution,
- reduce or unwind problem until base case.
- write a solution for base case and for reduction
step.
8Recursive solution form
- if ( trivial case )
- solve directly
- else
- solve in terms of a slightly easier case
9Sorting a list
- Trivial case
- size of list is one or zero.
- General case
- Size of list is greater than 1.
- Slightly easier problem
- reduce general case to sort a list with one fewer
element.
10Sorting a list
- if ( list is empty or has one element )
- solution is easy do nothing
- else
- sort the list, assuming a way of sorting a
listwith one fewer element is available
11Recursive algorithm implementation
- Trivial case
- Solved directly.
- General case
- algorithm invokes itself to solve a slightly
reduced case. - solution is built from solution of slightly
reduced case.
12Recursive algorithm execution
- Results in a chain of self-calls,
- each a slightly easier problem to solve that
previous. - Finally method is invoked with trivial case.
13Recursive algorithm correctness
- Must guarantee that general case will eventually
reduce to basic case.
14Example Exponentiation
- public static int power (int number, int
exponent) - The specified number raised to the specified
power. - require exponent gt 0
15Exponentiation iterative solution
public static int power (int number, int
exponent) int result 1 int count
0 while (count ! exponent) result number
result count count 1 return
result
- Invariant result equals number raised to the
count power. - Exponent requirement to be gt 0 ensures iteration
will terminate.
16Exponentiation recursive solution
- Base cases raise integer to the power 0.
- General case raise integer to the power n, n is
an integer and n gt 0. - Reduction step raising a number to the power
n-1.
17Exponentiation recursive solution
- Compute number to the power n, assuming we have
already computed number to the power n-1. - If we have numbern-1,
- multiply this value by number to get numbern.
- number n-1 is gotten by a self-call
- power (number, n-1)
18Exponentiation recursive solution
- /
- The specified number raised to the specified
power. - require exponent gt 0
- /
- public static int power (int number, int
exponent) - int result
- if (exponent 0)
- result 1
- else
- result number power(number,exponent-1)
- return result
19Tracing recursion invoking power(2,3)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
3
exponent
result
20Tracing recursion invoking power(2,3)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
3
exponent
result
21Tracing recursion invoking power(2,3)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
3
exponent
result
invoke
22Tracing recursion invoking power(2,2)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
2
exponent
result
23Tracing recursion invoking power(2,2)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
2
exponent
result
24Tracing recursion invoking power(2,2)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
2
exponent
result
invoke
25Tracing recursion invoking power(2,1)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
1
exponent
result
26Tracing recursion invoking power(2,1)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
1
exponent
result
27Tracing recursion invoking power(2,1)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
1
exponent
result
invoke
28Tracing recursion invoking power(2,0)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
0
exponent
result
29Tracing recursion invoking power(2,0)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
0
exponent
result
1
30Tracing recursion invoking power(2,0)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
0
exponent
result
1
31Tracing recursionresuming power(2,1)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
1
exponent
result
Result of previous call
1
32Tracing recursion resuming power(2,1)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
1
exponent
result
2
33Tracing recursion resuming power(2,1)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
1
exponent
result
2
34Tracing recursion resuming power(2,2)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
2
exponent
result
Result of previous call
2
35Tracing recursion resuming power(2,2)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
2
exponent
result
4
36Tracing recursion resuming power(2,2)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
2
exponent
result
4
37Tracing recursion resuming power(2,3)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
3
exponent
result
Result of previous call
4
38Tracing recursion resuming power(2,3)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
3
exponent
result
8
39Tracing recursion resuming power(2,3)
if (exponent 0) result 1 else result
number power(number,exponent-1) return
result
number
2
3
exponent
result
8
40Finding the minimum element Recursive version
- public int minFinalExam (ListltStudentgt students)
- The lowest final exam grades of the specified
Students. - require students.size() gt 0
41Finding the minimum element Recursive version
- Base case find smallest on list containing one
element. - General case find smallest on list with n
elements, where n gt 1. - Reducing general case find smallest on list with
n-1 elements.
42Finding the minimum element Recursive version
- how to find smallest of n elements, assuming we
know how to find smallest of n-1 elements. - Find smallest of the n-1 elements after first.
- Find smallest of this and the first.
43Finding the minimum element Recursive version
- private int minFinalExam (ListltStudentgt
students, int first) - The lowest final exam grades of Students on the
list with indexes greater than or equal to first. - require 0 lt first first lt students.size()
- public int minFinalExam (ListltStudentgt students)
- return minFinalExam(students,0)
44Finding the minimum element Recursive version
- private int minFinalExam (ListltStudentgt
students,int first) - int smallest
- int gradeOfFirst students.get(first).finalExam(
) - if (first students.size()-1)
- smallest gradeOfFirst // the base case
- else // the general case
- int minOfRest minFinalExam(students,first1)
- if (minOfRest lt gradeOfFirst)
- smallest minOfRest
- else
- smallest gradeOfFirst
-
- return smallest
45Selection sort recursive version
- Base cases sort an empty list or with 1 element.
- General case sort a list containing n elements,
n gt 1. - Reducing general case sort a list containing n-1
elements.
46Selection sort recursive version
- Find the smallest element and put it in first
place. - Sort the remaining n-1 elements.
- Note sorting the remaining n-1 elements, refers
to a segment of the list
first
remaining n-1 elements
47Selection sort recursive version
- private static ltElementgt void selectionSort
(ListltElementgt list, int first, OrderltElementgt
order) -
- if (first lt list.size())
- find the smallest element and put it first
- sort the remaining n-1 elements
-
48Selection sort recursive version
- private static ltElementgt void selectionSort
(ListltElementgt list, int first, OrderltElementgt
order) -
- if (first lt list.size())
- int small
- smallestOf(list,first,list.size()-1,order
) - interchange(list,first,small)
- selectionSort(list,first1,order)
-
49Selection sort recursive version
- public static ltElementgt void selectionSort
( ListltElementgt list, OrderltElementgt order) - selectionSort(list,0,order)
50Towers of Hanoi
- move stack of disks from starting peg to one of
the other pegs. Disks are moved one at a time,
and a disk can never be placed on top of a
smaller one.
51Example of moves with 3 discs
52Example of moves with 3 discs
53Example of moves with 3 discs
54Example of moves with 3 discs
55Example of moves with 3 discs
56Example of moves with 3 discs
57Example of moves with 3 discs
58Example of moves with 3 discs
59Example of moves with 3 discs
60Example of moves with 3 discs
61Example of moves with 3 discs
62Example of moves with 3 discs
63Example of moves with 3 discs
64Example of moves with 3 discs
65Example of moves with 3 discs
66PuzzleSolver method moveTower
- public void moveTower (int size, int from, int
to) - Move a tower of the specified number of disks
from the specified starting peg to the specified
destination peg. - require size gt 1 1 lt from from lt 3 1 lt
to to lt 3 from ! to
67PuzzleSolver method moveTower
- It uses a private method to move one disc
private void moveDisk (int from, int to) Move a
single disk from the specified peg to the
specified destination. require 1 lt from
from lt 3 1 lt to to lt 3 from ! to
68PuzzleSolver method moveTower
- Base case a tower with 1 disc.
- General case a tower with n discs.
- Reduction case move a tower with n-1 discs.
69PuzzleSolver method moveTower
- Reduce problem of moving n disks to problem of
moving n-1 - Move n-1 disks from the starting peg to the
other peg. - Move a disk from the starting peg to the
destination peg. - Move n-1 disks from the other peg to the
destination peg. - To find other peg
- subtract source peg number (from) and destination
peg number (to) from 6 ( 1 2 3).
70PuzzleSolver moveTower implementation
- public void moveTower (int n, int from, int to)
-
- if (n 1)
- moveDisk(from,to)
- else
- int other 6-from-to // not from or to
- moveTower(n-1,from,other)
- moveDisk(from,to)
- moveTower(n-1,other,to)
-
71PuzzleSolver moveDisk
private void moveDisk (int from, int to)
System.out.println( "Move a disk from peg "
from " to peg " to '.')
72PuzzleSolver moveDisk
- Not very satisfactory.
- PuzzleSolver is a model class
- should be independent of the user interface.
73PuzzleSolver moveDisk
- Better way to implement moveDisk
- Use the Observer pattern.
- When output client is notified, pass move to make
public class Move A move in the Towers puzzle.
Pegs are numbered 1, 2, 3. public Move (int
from, int to) Create a move of a disk from the
peg from to the peg to. public int from () Peg
the disk is moved from. public int to () Peg
the disk is moved to.
74PuzzleSolver moveDisk
- private void moveDisk (int from, int to)
- setChanged()
- notifyObservers(new Move(from, to))
75Quicksort
- Quicksort
- puts an arbitrary element in proper position,
- smaller elements are below it.
- larger elements are above it.
- Sublists 2, 3 are recursively sorted.
76Quicksort
- Implement a private method to sort a list
segment. - sort calls method with entire list
public static ltElementgt void quickSort
( ListltElementgt list, OrderltElementgt order)
quickSort(list,0,list.size()-1,order) //Sor
t list elements indexed first through last. //
require 0 lt first last lt list.size() private
static ltElementgt void quickSort ( ListltElementgt
list, int first, int last, OrderltElementgt order)
77Quicksort
- Base case
- an empty list or a list with a single element.
- The general case is handled by the three steps
- puts an arbitrary element in proper position,
- smaller elements are below it.
- larger elements are above it.
- Sublists 2, 3 are sorted.
78Quicksort partition
- This method positions pivot such that
- Smaller elements in list are below it.
- Larger elements in list are above it.
- Reports where pivot was placed.
79Quicksort
- private static ltElementgt void quickSort
( ListltElementgt list, int first, int
last, OrderltElementgt order) - if (first lt last)
- int position // pivot index
- position partition(list,first,last,order)
- quickSort(list,first,position-1,order)
- quickSort(list,position1,last,order)
-
80Quicksort partition
- Choose middle element of sublist as pivot
element.
- move the pivot element into the last position
81Quicksort partition
pi
i
82Quicksort partition
- i, pi start at 0
- Compare i-th entry with pivot
pi
i
83Quicksort partition
- Compare i-th entry with pivot.
pi
i
84Quicksort partition
- Compare i-th entry with pivot.
pi
i
85Quicksort partition
- Compare i-th entry with pivot. Its less.
- Swap and increment indices.
pi
i
86Quicksort partition
- Compare i-th entry with pivot.
1
23
46
56
3
18
30
73
19
28
12
61
41
45
55
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
i
87Quicksort partition
- Compare i-th entry with pivot. Its less.
- Swap and increment indices.
1
23
46
56
3
18
30
73
19
28
12
61
41
45
55
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
88Quicksort partition
- Compare i-th entry with pivot.
23
46
56
3
18
30
73
19
28
12
61
1
45
55
41
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
89Quicksort partition
- Compare i-th entry with pivot.
23
46
56
3
18
30
73
19
28
12
61
1
45
55
41
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
90Quicksort partition
- Compare i-th entry with pivot. Its less.
- Swap and increment.
23
46
56
3
18
30
73
19
28
12
61
1
45
55
41
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
91Quicksort partition
- Compare i-th entry with pivot. Its less.
- Swap and increment indices.
45
46
56
3
18
30
73
19
28
12
61
1
23
55
41
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
92Quicksort partition
- Compare i-th entry with pivot. Its less.
- Swap and increment indices.
45
46
56
18
30
73
19
28
12
3
1
23
55
41
61
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
93Quicksort partition
- Compare i-th entry with pivot.
45
46
56
55
30
73
19
28
12
3
1
23
18
41
61
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
94Quicksort partition
- Compare i-th entry with pivot. Its less
- Swap and increment indices.
45
46
56
55
30
73
19
28
12
3
1
23
18
41
61
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
95Quicksort partition
- Compare i-th entry with pivot.
45
46
56
55
30
73
41
28
12
3
1
23
18
19
61
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
96Quicksort partition
- Loop exited. Swap pivot with pi.
45
46
56
55
30
73
41
28
12
3
1
23
18
19
61
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
97Quicksort partition
45
28
56
55
30
73
41
46
12
3
1
23
18
19
61
(5)
(6)
(8)
(7)
(9)
(10)
(11)
(13)
(12)
(14)
(0)
(1)
(3)
(2)
(4)
98partition implementation
private static ltElementgt int partition
(ListltElementgt list, int first, int last,
OrderltElementgt order) int pi // pivot
index int i // index of the next to
examine Element pivot // pivot item int mid
(firstlast)/2 pivot list.get(mid) interchan
ge(list,mid,last) // put pivot item at end. pi
first i first while (i ! last) //
list.get(last) is pivot item if
(order.inOrder(list.get(i),pivot))
interchange(list,pi,i) pi
pi1 i i1 interchange(list,pi,last)
// put pivot item in place return pi
99Indirect Recursion
- Method m1 invokes m2 which invokes m3 which
invokes mn which invokes m1.
100Indirect Recursion RemoveSet
- Given a balanced string of parentheses as
argument, removes the first balanced substring
from the front. - Examples
- removeSet("()") ? ""
- removeSet("()()()()") ? "()()()"
- removeSet("((()))") ? ""
- removeSet("(()()(()()))()(())") ? "()(())"
101RemoveSet design
- Remove first (
- Invoke reduceClosed for matching )
private String reduceClosed (String s) A String
equal to specified String with first substring
with one more closed parenthesis than open
parenthesis removed.
102RemoveSet design
- For example,
- reduceClosed(")") ? "
- reduceClosed(")()()") ? "()()
- reduceClosed("(()()))(()) ? "(())
- reduceClosed("()()(()()))()(())") ? "()(())"
103RemoveClosed design
- Basic case first character is ).
- General case first character of s is open
parenthesis then s starts with balanced
substring. - Remove balanced substring,
- Recursively apply method to whats left.
104RemoveClosed design
- Use removeSet to remove balanced substring
private String reduceClosed (String s) if
(head(s) ')') return tail(s) else //
head(s) '(, remove balanced set return
reduceClosed(removeSet(s))
105Backtracking
- Algorithmic technique for solving problems that
cannot be solved directly. - Backtracking is used when a large set of possible
solutions must be examined to find an actual
solution to the problem.
106Backtracking
- For backtracking to be an appropriate technique,
problem solution must be - a composite, made up of parts
- constructible in a series of steps, with each
step adding a piece to the solution. - At each step there will several possible ways of
extending the partial solution of the previous
step. Some of these alternative will lead to a
solution, others will not.
107Backtracking example
- suppose we have a maze consisting of a set of
rooms connected by passages. - Each room is connected to one or more passages.
- A passage may lead to another room, or may lead
to the maze exit.
108Backtracking example
- For instance, a maze with seven rooms might look
like this, where the rooms are lettered and the
doors are labelled north, south, east, west.
109Backtracking example
- Problem find a path from a given room to the
exit. - Note solution is composite
- to reach the exit from room F, go south to room
D, west to room C, east to room E, east to the
exit. - The path can be constructed in a series of steps,
each step adding a component to the partial
solution built in the previous step.
110Backtracking example
- At each step, there may be several alternatives.
- For example, the first step in the above solution
is go south to room D. - This partial solution can be extended in two
ways go west to room C or go south to room
G. - The first option leads to a solution, while the
second does not. Room G is a dead end.
111Backtracking example
- Backtracking works by repeatedly extending a
partial solution until a solution is found or a
dead end is reached. - A dead end is simply a state that cannot be
further extended. - If a dead end is reached, the algorithm backs
up to the most recent point at which untried
possibilities exist, and tries one.
112Backtracking example
- To see how this works, suppose we are trying to
reach the exit from room A in the above maze. - room A
- go north to room B
- dead end back up to room A.
- go south to room C
- go north to room D
- go east to room F
- dead end back up to room D.
- go south to room G
- dead end back up to room D.
- no more choices (dead end) back up to room C
- go east to room E
- go east to exit.
113Implementing backtracking
- Implement a backtracking algorithm for the maze
traversal problem. - A Maze is composed of a number of Rooms, with
each Room connected to a number of other Rooms.
114Implementing backtracking
- public ListltRoomgt connections ()
- The list of Rooms this Room is connected to.
- public boolean isExit ()
- This Room is a maze exit.
115Implementing backtracking
- public class PathPoint
- A Room and a connection from the Room.
- public PathPoint (Room room, int connection)
- Create a new PathPoint.
- require 0ltconnection connection lt
room.connections().size()
116Implementing backtracking
- A path is a list of PathPoints modeling a
sequence of connected Rooms. - If PathPoint B,j follows A,i on list, then
connection i from Room A leads to Room B. That
is, A.connections(i) B. - Require path has no repeated Rooms.
- A Path from Room A to H is (A,1),(C,2),(E,1)
117Implementing backtracking
- write a method that will produce an exit path
from a specified Room
public ListltPathPointgt exitPathFrom (Room room) A
path leading from the specified Room to an exit
returns null if no path exists.
- use an auxiliary method that takes a partial
solution and extends it.
private ListltPathPointgt extendedPathFrom (Room
room, ListltPathPointgt path) The specified path
extended from the specified Room to an exit.
Returns null if the path cannot be extended to an
exit. The specified path must be empty or lead to
the specified Room.
118Implementing backtracking
- The public method calls the auxiliary method with
an empty initial path
public ListltPathPointgt exitPathFrom (Room room)
return extendedPathFrom( room, new
DefaultListltPathPointgt())
119Implementing backtracking
private ListltPathPointgt extendedPathFrom (
Room room, ListltPathPointgt path) if
(room.isExit()) return path else
boolean found false ListltPathPointgt
solution null int i 0 while (i lt
room.connections().size() !found)
// get a Room to extend the path
Room nextRoom room.connections().get(i)
if (!pathContains(path, nextRoom))
ListltPathPointgt extendedPath path.copy().add(new
PathPoint(room,i)) solution
extendedPathFrom(nextRoom,extendedPath)
found solution ! null
i i1 return
solution
120Object recursion
- Examine another form of recursion, called
structural recursion or object recursion. - Structural recursion uses object structure in a
recursive manner to derive problem solutions.
121Object recursion
- Two flavors of solver objects
- General problem solver,
- the trivial problem solver.
- We make these children of a common abstract
parent
122Object recursion
- Construct an odometer-like counter consisting of
a sequence of digits. - A digit turning over from 9 to 0 causes its left
neighbor to increment - A solution is simply a stable state of the
counter, one in which all digits are set. - to find first solution that is, reset all digits
to 0. - to find next solution increment the counter by
1. - There is a final solution, all digits are 9.
- We specify that attempting to find the next
solution after the final state will fail i.e., a
counter that is all 9s will not turn over to all
0s.
123Object recursion
- Digit general solver class.
- Each Digit instance is responsible for a single
digit of the solution. - Each Digit has an associate, the Digit to its
left. - A Digit extends solution provided by its
associate. - Digits are linked together to form the
counter. - The high-order (left-most) Digit has a NullDigit
as its associate. (it needs no associate). - NullDigit trivial solver class.
- The logic in the NullDigit simply ends the
recursion.
124Object recursion DigitCounter
- Note a Digit and its associate have the same
structure.
125Object recursion DigitCounter
public class DigitCounter private
VirtualDigit lowDigit // right-most
digit / Create a new DigitCounter with
the specified number of digits. _at_require
digits gt 1 / public DigitCounter (int
digits) VirtualDigit d new
NullDigit() for (int i 1 i lt digits i
i1) d new Digit(d) lowDigit d
126Object recursion DigitCounter
public void first () lowDigit.first() pub
lic void next () lowDigit.next() public
boolean solved () return lowDigit.solved()
public String toString () return
lowDigit.toString() //definition of
VirtualDigit interface // Digit
class, NullDigit class. //end DigitCounter
127Object recursion DigitCounter
- DigitCounter contains a private interface
implemented by Digit and NullDigit.
private interface VirtualDigit public boolean
solved () public void first () public void
next () public String toString ()
128Object recursion Digit
- Digit class
- Implements VirtualDigit interface.
- Contains an int as data component for the digit.
- When given command first, instructs left neighbor
to find first number, and then sets itself
to 0. - When given the command next,
- it increments its digit if its not 9.
- If its digit is 9, it instructs its left neighbor
to increment, and sets itself to 0. - In each case checks neighbor was successful.
129Object recursion Digit
private class Digit implements VirtualDigit
private VirtualDigit associate // left nghb
private boolean solved // valid num
private int digit // my digit public
Digit (VirtualDigit associate) this.associate
associate this.digit 0 this.solved
false public boolean solved ()
return solved public void first ()
associate.first() if (associate.solved())
digit 0 solved true else solved
false
public void next () if (digit lt 9)
digit digit 1 solved true
else associate.next() if
(associate.solved()) digit 0 solved
true else solved false public
String toString () if (solved) return
associate.toString() digit else
return "No solution" //end Digit
130Object recursion NullDigit
private class NullDigit implements VirtualDigit
private boolean solved public NullDigit ()
this.solved false public boolean
solved () return solved public void
first () solved true public void next
() solved false public String toString
() if (solved) return "" else return
"No solution"
131Summary
- Introduced the problem solving technique of
recursion. - Two forms of recursive computation
- algorithmic recursion, in which a method invokes
itself directly or indirectly, - object recursion, based on the creation of
composite object structure in which the structure
of a component is the same as that of the
composite object.
132Summary
- Algorithmic recursion solution logic depends on
- identifying simple base cases that can be easily
solved directly, and - describing how to reduce the general case to one
that is slightly simpler that is, slightly
closer to a base case. - The method that actualizes this logic invokes
itself to solve the slightly simpler case to
which the general case is reduced.
133Summary
- A well-known algorithm using direct recursion is
quick sort. - Quick sort is much more efficient that the
selection and bubble sorts generally requiring on
the order of n?log2n steps to sort a list of n
elements. - Quick sort works by
- positioning an arbitrary element, with smaller
elements below and larger elements above. - list segments containing the smaller elements and
the larger elements are then recursively sorted.
134Summary
- Indirect recursion, a method is invoked before it
returns through a sequence of other method
invocations. That is, - method m1 invokes m2 which invokes m3 which
invokes mn which invokes m1. - When indirect recursion is used, we generally set
a collection of mutually recursive methods.
135Summary
- Backtracking is an algorithmic technique for
examining a set of possible solutions to a
problem in an organized way in order to find an
actual solution. - Solution to problem is a composite, made up of
several pieces. - Each step in a backtracking algorithm attempts to
extend partial solution produced by the previous
step. - If not possible to extend partial solution,
algorithm backs up to find another partial
solution to extend.
136Summary
- Using object recursion, a solver object is
structured with a similar solver object as an
associate. - Solver object delegates the responsibility of
solving a simpler version of the problem to its
associate, and then extends the solution provided
by the associate. - Recursive nature of approach is seen here a
solution to the general case is found by using a
solution to a simpler case given by the associate.