CS2006Ch02C

COSC 2006 Data Structures I
Recursion 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
A
B
only reasonable solution
Given:

N disks & three poles:








C
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
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
1
B
A
C
2
B
A
C
3
B
Towers of Hanoi - Stages
A
C
4
B
A
C
B
6
5
A
C
7
B
C
A
A
C
8
B
B
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
B
a) Initial state
b) Move N-1 disks
from A to C
c) Move 1 disk
from A to B
d) Move N-1 disks
from C to 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 - Algorithm
public static void
solveTowers(int n, char source, char dest, char intermed)
{
if (n == 1)
System.out.println("move a disk from " + source
+ " to " + dest);
else
{
2
solveTowers(n-1, source, intermed, dest);
solveTowers(1, source, dest, intermed);
solveTowers(n-1, intermed, dest, source);
}
3
}
original call: solveTowers ( 3, 'A', 'C', 'B');
1
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
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


19
either farther to or the same “distance”
from
Review

In a sorted array, the kth smallest item is
given by ______.
anArray[k-1]
 anArray[k]
 anArray[SIZE-k]
 anArray[SIZE+k]

20
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

21
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

22
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

23
Review

A recursive solution that finds the factorial
of n generates ______ recursive calls.
n-1
 n
 n+1
 n*2

24
Review

In the Fibonacci sequence, which of the
following integers comes after the
sequence 1, 1, 2, 3?
3
 4
 5
 6

25