### Chapter 3 - Department of Computer Science

```COMPSCI 105 S2 2014
Principles of Computer Science
Recursion 3
Agenda

Agenda





Textbook:



2
The Fibonacci Sequence
The Towers of Hanoi
Binary search
Recursion and efficiency
Problem Solving with Algorithms and Data Structures
Chapter 4 – Recursion
Chapter 5 – Searching
COMPSCI105
22
22.1 The Fibonacci Sequence
The Fibonacci Sequence

Describes the growth of an idealised (biologically
unrealistic) rabbit population, assuming that:




3
Rabbits never die
A rabbit reaches sexual maturity exactly two months after birth,
that is, at the beginning of its third month of life
Rabbits are always born in male-female pairs
At the beginning of every month, each sexually mature malefemale pair gives birth to exactly one male-female pair
COMPSCI105
22
22.1 The Fibonacci Sequence
The Fibonacci Sequence

Problem


How many pairs of rabbits are alive in month n?
Example:

rabbit(5) = 5
1
Month
2

Recurrence relation
rabbit(n) = rabbit(n-1)
+ rabbit(n-2)
3
4
5
4
COMPSCI105
22
22.1 The Fibonacci Sequence
Recursive Definition

Base cases


rabbit(2), rabbit(1)
Recursive
rabbit(n) =

1 if n is 1 or 2
rabbit(n-1) + rabbit(n-2)
Fibonacci sequence

The series of numbers rabbit(1), rabbit(2), rabbit(3), and so on
The sequence of numbers
rabbit(n) for all n is called
Fibonacci Sequence or
Fibonacci numbers.
5
if n > 2
def rabbit(n):
if n <=2:
return 1
return rabbit(n-1) + rabbit(n-2)
COMPSCI105
22
22.1 The Fibonacci Sequence
rabbit(6)
rabbit(6)
return rabbit(5)+rabbit(4)
rabbit(5)
return rabbit(4)+rabbit(3)
rabbit(4)
return rabbit(3)+rabbit(2)
rabbit(3)
return rabbit(2)+rabbit(1)
rabbit(2)
return 1
6
rabbit(2)
return 1
rabbit(4)
return rabbit(3)+rabbit(2)
rabbit(3)
rabbit(3)
return rabbit(2)+rabbit(1) return rabbit(2)+rabbit(1)
rabbit(2)
return 1
rabbit(1)
return 1
rabbit(2)
return 1
rabbit(2)
return 1
rabbit(1)
return 1
rabbit(1)
return 1
COMPSCI105
22
22.1 The Fibonacci Sequence
Examples:
Fibonacci
Spiral
Fibonacci
Tiling
7
COMPSCI105
22
22.2 The Towers of Hanoi
2.6 The Towers of Hanoi

Puzzle consists of n disks and three poles




8
The disks are of different size and have holes to fit
themselves on the poles
Initially all the disks were on one pole, e.g., pole A
The task was to move the disks, one by one, from pole A to
another pole B, with the help of a spare pole C.
Due to its weight, a disks could be placed only on top of
another disk larger than itself
COMPSCI105
22
22.2 The Towers of Hanoi
Solution

If you have only one disk (i.e., n=1),


If you have more than one disk,



simply ignore the bottom disk and solve the problem for n-1
disk, with pole C is the destination and pole B is the spare
Then move the largest disk from pole A to B; then move the n-1
disks from the pole C back to pole B
We can use a recursion with the arguments:

9
move it from pole A to pole B
Number of disks, source pole, destination pole, spare pole
COMPSCI105
22
22.2 The Towers of Hanoi
Solution defifhanoi(count,source,destination,spare):
count is 1:
Move a disk directly from source to destination
Move count-1 disks from source to spare
Applyfrom
function
recursively
Move 1 disk
source
to destination
to
move
these
three
disks.to destination
Move count-1 disk from spare
Source
Source
10
destination
destination
spare
Source
Source
spare
COMPSCI105
destination
destination
spare
spare
22
22.2 The Towers of Hanoi
Pseudo code for the recursive solution

Satisfies the four criteria of a recursive solution




Recursive method calls itself
Each recursive call solves an identical, but smaller problem
Stops at base case
Base case is reached in finite time
def hanoi(count, source, destination, spare):
if count <= 1:
print ("base case: move disk from", source, "to", destination)
else:
1 hanoi(count - 1, source, spare, destination)
2 print ("step2: move disk from", source, "to", destination)
3 hanoi(count - 1, spare, destination, source)
11
COMPSCI105
22
def hanoi(count, source, dest, spare):
if count <= 1:
print ("base case: move disk from", source, "to", dest)
else:
hanoi(count - 1, source, spare, dest)
print ("step2: move disk from", source, "to", dest)
hanoi(count - 1, spare, dest, source)
Example: hanoi(3, "A", "B", "C")
hanoi(3, ‘A’, ‘B’, ‘C’)
Count = 3
Source = A
Dest = B
Spare = C
?
?
hanoi(2, ‘A’, ‘C’, ‘B’)
Count = 2
Source = A
Dest = C
Spare = B
?
3 Steps
3 Steps
?
Print: from A to B
A
B
hanoi(1, ‘A’, ‘B’, ‘C’
Count = 1
Source = A
Dest = B
Spare = C
hanoi(1, ‘B’, ‘C’, ‘A’
Count = 1
Source = B
Dest = C
Spare = A
C
12
3 Steps
Base case:
Print: from A to B
A
B
C
C
Print: from A to C
hanoi(2, ‘C’, ‘B’, ‘A’)
Count = 2
Source = C
Dest = B
Spare = A
?
Check
Animation
B
A
A
B
C
A
B
C
Base case:
Print: from B to C
hanoi(1, ‘C’, ‘A’, ‘B’
Count = 1
Source = C
Dest = A
Spare = B
Base case:
Print: from C
to A
A
B
C
A
B
Print: from C to B
hanoi(1, ‘A’, ‘B’, ‘C’
Count = 1
Source = A
Dest = B
Spare = C
?
COMPSCI105
C
Base case:
Print: from A
to B
22
22.2 The Towers of Hanoi
Call Tree
hanoi(3…) uses 10 calls, a top-level one and 9 recursive calls

hanoi(3, ‘A’, ‘B’, ‘C’)
hanoi(2, ‘A’, ‘C’, ‘B’)
hanoi(2, ‘C’, ‘B’, ‘A’)
Move A -> B
A
B
C
hanoi(1, ‘A’, ‘B’, ‘C’)
hanoi(1 , ‘C’, ‘A’, ‘B’)
Move A -> C
A
B
C
hanoi(1, ‘B’, ‘C’, ‘A’)
A
13
Move C -> B
B
C
A
B
A
C
COMPSCI105
B
C
hanoi(1, ‘A’, ‘B’, ‘C’)
A
B
C
A
C
B
22
22.3 Binary Search
Binary Search

Problem: look for an element (key) in an ordered collection


Sequential search



(e.g. find a word in a dictionary)
Starts at the beginning of the collection
Looks at every item in the collection in order until the item being
searched for is found
Binary search


Cost?
Repeatedly halves the collection and determines which half could
contain the item
Uses a divide and conquer strategy
Search dictionary
OR
Search first half of dictionary
14
Search first half of dictionary
COMPSCI105
22
22.3 Binary Search
Implementation

Implementation issues:





15
How will you pass “half of list” to the recursive calls to
binary_search?
How do you determine which half of the list contains value?
What should the base case(s) be?
How will binary_search indicate the result of the search?
Example: a sorted list
COMPSCI105
22
22.3 Binary Search
Algorithm Design

Base case:



If array is empty number is not in the list, or
If element is the one we look for return it
Recursive call



Determine element in the middle
If the one we look for is smaller than element in the middle then
search in the left half
Otherwise search in the right half of the list
Left half: [first .. mid-1]
0
first
16
1
2
Right half: [mid+1 .. last]
3
4
5
6
mid = (first + last)/2
COMPSCI105
7
8
9
last
22
22.3 Binary Search
Example Code
def binary_search(num_list, first, last, value):
index = 0
if first > last:
index = -1
else:
mid = (first + last) // 2
if value == num_list[mid]:
index = mid
elif value < num_list[mid]:
index = binary_search(num_list, first, mid-1, value)
else:
index = binary_search(num_list, mid+1, last, value)
return index
17
COMPSCI105
22
index

22.3 Binary Search
0
1
2
3
4
5
6
7
Call Tree
1
5
9
12
15
21
29
31
A successful search for 9:
value 9
first  0
last  7
0 7
mid
3
2
value  anArray[3]

binary_search(list,0,7,9)
value 9
first  2
last  2
22
mid
2
2
value  anArray[2]
binary_search(list,0,2,9)
value 9
first  0
last  2
02
mid
1
2
value  anArray[1]
binary_search(list,2,2,9)

return 2

18
COMPSCI105
22
index

22.3 Binary Search
0
1
2
3
4
5
6
7
Call Tree
1
5
9
12
15
21
29
31
An unsuccessful search for 6:
value 6
first  0
last  7
0 7
mid
3
2
value  anArray[3]

binary_search(list,0,7,6)
value 6
first  2
last  2
binary_search(list,0,2,6)
value 6
first  0
last  2
02
mid
1
2
value  anArray[1]
mid
value  anArray[2]
binary_search(list,2,2,6)

binary_search(list,2,1,6)
19
22
2
2
COMPSCI105
value 6
first  2
last  1
first  last
return 1
return -1
22
22.4 Efficiency
Recursion and Efficiency


Some recursive solutions are so inefficient that they
should not be used
Factors that contribute to the inefficiency of some
recursive solutions



20
Inherent inefficiency of some recursive algorithms
Note: The recursive methods binarySearch and
solveTowers are quite efficient, but the fact and
rabbit are inefficient
COMPSCI105
22
22.4 Efficiency
Recursion and Efficiency


Do not use a recursive solution if it is inefficient and if
you have a clear, efficient iterative solution
Factorial’s recursive solution



Rabbit counting recursive solution



21
Iterative method is more efficient
Inherent inefficiency of recursive algorithms
It computes same values over and over again, e.g., rabbit(7)
computes rabbit (3) five times.
Use rabbit’s recurrence relation to construct an efficient
iterative solution
COMPSCI105
22
22.4 Efficiency
Iterative Solution
def iterative_rabbit(n):
previous = 1
current = 1
next_elt = 1
for i in range(3, n+1):
next_elt = current + previous;
previous = current;
current = next_elt
return next_elt
22
COMPSCI105
22
Exercise

Given the following:


my_list = [0, 1, 2, 8, 13, 17, 19, 32, 42]
Draw the call tree of


23
binary_search(my_list,0,8,3)
binary_search(my_list,0,8,13)
COMPSCI105
22
```