COSC 2006 Data Structures IRecursion III
kth smallest Can be solved by sorting, but this does more work
than needed (why?) solving kth smallest for all k
More efficient solution possible: Pick an element, any element partition the other elements into two sets: those smaller (S1)
and those bigger (S2) If S1 has k-1 members, we got lucky! If S1 has at least k members, recurse to find the kth smallest
in S1 Otherwise recurse to find the kth smallest in S2 …
kth smallest: Devil in the details What about this last case? We dispensed with |S1| + 1 elements! So we are looking for the ___th
smallest element in S2(k - (|S1| + 1))th
Need to “pass” subarray with first, last
So, |S1| = pivotIndex - first
kth smallest: partial code
This motivates the details:
kSmall(k, anArray, first, last)
choose a pivotIndex
if (k < pivotIndex - first + 1)
return kSmall(k, anArray, first, pivotIndex-1)
else if (k == pivotIndex - first + 1)
return p
else
return kSmall(k - (pivotIndex-first+1), anArray, pivotIndex+1, last)
Problems with Recursion
Memory (stack) exhaustion: if many stack frames are pushed - can run out of space for stack
Time:each recursive call requires time to set up a new stack frame, copy in actual parameter values and transfer execution
Problems with Recursion
Any recursive algorithm can be rewritten using iterative technique - it will be longer and more likely to have problems but will run faster.
Recursion Vs Iteration
Note that just because we can use recursion to solve a problem, that does not mean this is the optimal solution.
For instance, we usually would not use recursion to solve the sum of 1 to N problem, because the iterative version is easier to understand and requires less memory is N is a large number.
Recursion Vs Iteration
The iterative solution is easier to understand:
sum = 0; for(int number = 1; number <=N; number++)
sum += number;
Recursion has memory overhead. However, for some problems, recursion provides an elegant solution, often cleaner than an iterative version
Example: Towers of Hanoi
For some problems, recursive solution is the only reasonable solution
Given: N disks & three poles:
A the source B the destination C the spare (temporary)
The disks are of different sizes & have holes in the middle Only one disk can be removed at a time A larger disk can't be placed on a smaller one Initially all disks are on pole A
Required: Move the disks, one-by-one, from pole(peg) A to B, using pole C as spare
A B C
Example: Towers of Hanoi
Solution: Only one disk (N=1, First base case):
Move the disk from the source peg A to the destination peg B
Only two disks (N=2, Second base case): Move the top disk from peg A to peg C Move the second disk from peg A to peg B Move the top disk from peg C to peg B
Example: Towers of Hanoi
Solution: Three disks (N=3):
Move top disk from peg A to peg B Move second disk from peg A to peg C Move top disk from peg B to peg C Move the remaining bottom disk from peg A to peg
B Move the top disk from peg C to peg A Move second disk from peg C to peg B Move top disk from peg A to peg B A C B
Towers of Hanoi
A C B1
A C B2
A C B3
Towers of Hanoi - Stages
A C B
4
A C B
5
A C B
6
A C B
7
A C B
8
Example: Towers of Hanoi
Solution: General Solution (N-1) disks:
Move the top (N-1) disks to Temp pole Move the bottom disk to the destination Move the N-1 disks from Temp to the destination
Example: Towers of Hanoi
Solution: General Solution (N-1) disks:
a) Initial state
b) Move N-1 disks from A to C
c) Move 1 diskfrom A to B
d) Move N-1 disksfrom C to B
A B C
Towers of Hanoi
First let’s play with blocks …
solveTowers(count, source, dest, spare) if (count is 1) { move a disk directly from source to dest else solveTowers(count-1, source, spare, dest) solveTowers(1, source, dest, spare) solveTowers(count-1, spare, dest, source)
Towers of Hanoi - Algorithmpublic static voidsolveTowers(int n, char source, char dest, char intermed){ if (n == 1) System.out.println("move a disk from " + source + " to " + dest); else { solveTowers(n-1, source, intermed, dest); solveTowers(1, source, dest, intermed); solveTowers(n-1, intermed, dest, source); }}original call: solveTowers ( 3, 'A', 'C', 'B');
1
2
3
Example: Towers of Hanoi
Observations Solution analog to mathematical induction
If we can solve the problem for N-1 disks, then we can solve it for N disks
In each move, the source, destination, and temporary poles change locations
Three recursive calls inside the function
19
Review When you solve a problem by solving two or
more smaller problems, each of the smaller problems must be ______ the base case than the original problem. closer to farther to either closer to or the same “distance” from either farther to or the same “distance” from
20
Review In a sorted array, the kth smallest item is
given by ______. anArray[k-1] anArray[k] anArray[SIZE-k] anArray[SIZE+k]
21
Review A recursive solution that finds the factorial
of n always reduces the problem size by ______ at each recursive call. 1 2 half one-third
22
Review In the recursive solution to the kth
smallest item problem, the problem size decreases by ______ at each recursive call. 1 at least 1 half at least half
23
Review In the recursive solution to the Towers of
Hanoi problem, the number of disks to move ______ at each recursive call. decreases by 1 increases by 1 decreases by half increases by half
24
Review A recursive solution that finds the factorial
of n generates ______ recursive calls. n-1 n n+1 n*2
25
Review In the Fibonacci sequence, which of the
following integers comes after the sequence 1, 1, 2, 3? 3 4 5 6