Download presentation
Presentation is loading. Please wait.
Published byCecil Carr Modified over 9 years ago
1
COMPSCI 105 S2 2014 Principles of Computer Science Recursion 3
2
Agenda Agenda The Fibonacci Sequence The Towers of Hanoi Binary search Recursion and efficiency Textbook: Problem Solving with Algorithms and Data Structures Chapter 4 – Recursion Chapter 5 – Searching 22COMPSCI1052
3
22.1 The Fibonacci Sequence The Fibonacci Sequence Describes the growth of an idealised (biologically unrealistic) rabbit population, assuming that: 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 male- female pair gives birth to exactly one male-female pair 22COMPSCI1053
4
22.1 The Fibonacci Sequence The Fibonacci Sequence Problem How many pairs of rabbits are alive in month n? Example: rabbit(5) = 5 Recurrence relation rabbit(n) = rabbit(n-1) + rabbit(n-2) 1 2 3 4 5 Month 22COMPSCI1054
5
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)if n > 2 Fibonacci sequence The series of numbers rabbit(1), rabbit(2), rabbit(3), and so on def rabbit(n): if n <=2: return 1 return rabbit(n-1) + rabbit(n-2) def rabbit(n): if n <=2: return 1 return rabbit(n-1) + rabbit(n-2) The sequence of numbers rabbit(n) for all n is called Fibonacci Sequence or Fibonacci numbers. 22COMPSCI1055
6
22.1 The Fibonacci Sequence rabbit(6) rabbit(5) return rabbit(4)+rabbit(3) rabbit(4) return rabbit(3)+rabbit(2) rabbit(3) return rabbit(2)+rabbit(1) rabbit(3) return rabbit(2)+rabbit(1) rabbit(2) return 1 rabbit(2) return 1 rabbit(1) return 1 rabbit(1) return 1 rabbit(2) return 1 rabbit(6) return rabbit(5)+rabbit(4) rabbit(4) return rabbit(3)+rabbit(2) rabbit(3) return rabbit(2)+rabbit(1) rabbit(2) return 1 rabbit(1) return 1 rabbit(2) return 1 22COMPSCI1056
7
22.1 The Fibonacci Sequence Examples: Fibonacci Tiling Fibonacci Spiral 22COMPSCI1057
8
22.2 The Towers of Hanoi 2.6 The Towers of Hanoi Puzzle consists of n disks and three poles 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 22COMPSCI1058
9
22.2 The Towers of Hanoi Solution If you have only one disk (i.e., n=1), move it from pole A to pole B 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: Number of disks, source pole, destination pole, spare pole 22COMPSCI1059
10
22.2 The Towers of Hanoi Solution Apply function recursively to move these three disks. def hanoi(count,source,destination,spare): if count is 1: Move a disk directly from source to destination Move count-1 disks from source to spare Move 1 disk from source to destination Move count-1 disk from spare to destination def hanoi(count,source,destination,spare): if count is 1: Move a disk directly from source to destination Move count-1 disks from source to spare Move 1 disk from source to destination Move count-1 disk from spare to destination Source destination spare 22COMPSCI10510
11
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 22COMPSCI10511 def hanoi(count, source, destination, spare): if count <= 1: print ("base case: move disk from", source, "to", destination) else: hanoi(count - 1, source, spare, destination) print ("step2: move disk from", source, "to", destination) hanoi(count - 1, spare, destination, source) def hanoi(count, source, destination, spare): if count <= 1: print ("base case: move disk from", source, "to", destination) else: hanoi(count - 1, source, spare, destination) print ("step2: move disk from", source, "to", destination) hanoi(count - 1, spare, destination, source) 1 2 3
12
Example: hanoi(3, "A", "B", "C") 22COMPSCI10512 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 ? 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) 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) hanoi(1, ‘A’, ‘B’, ‘C’ Count = 1 Source = A Dest = B Spare = C Base case: Print: from A to B Print: from A to C hanoi(1, ‘B’, ‘C’, ‘A’ Count = 1 Source = B Dest = C Spare = A Base case: Print: from B to C Print: from A to B hanoi(2, ‘C’, ‘B’, ‘A’) Count = 2 Source = C Dest = B Spare = A ? hanoi(1, ‘C’, ‘A’, ‘B’ Count = 1 Source = C Dest = A Spare = B Base case: Print: from C to A Print: from C to B hanoi(1, ‘A’, ‘B’, ‘C’ Count = 1 Source = A Dest = B Spare = C Base case: Print: from A to B A B C AB C A B C A BC AB C A BC A B C 3 Steps Check Animation
13
22.2 The Towers of Hanoi Call Tree hanoi(3…) uses 10 calls, a top-level one and 9 recursive calls hanoi(2, ‘A’, ‘C’, ‘B’) hanoi(1, ‘A’, ‘B’, ‘C’) Move A -> C Move A -> B hanoi(1, ‘B’, ‘C’, ‘A’) hanoi(3, ‘A’, ‘B’, ‘C’) hanoi(2, ‘C’, ‘B’, ‘A’) hanoi(1, ‘C’, ‘A’, ‘B’) Move C -> B hanoi(1, ‘A’, ‘B’, ‘C’) A B C AB C A B C A BC AB C A BC A B C 22COMPSCI10513
14
22.3 Binary Search Binary Search Problem: look for an element (key) in an ordered collection (e.g. find a word in a dictionary) Sequential search 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 Repeatedly halves the collection and determines which half could contain the item Uses a divide and conquer strategy Search dictionary Search first half of dictionary OR Cost? 22COMPSCI10514
15
22.3 Binary Search Implementation Implementation issues: 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 22COMPSCI10515
16
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 0123456789 firstlastmid = (first + last)/2 Left half: [first.. mid-1]Right half: [mid+1.. last] 22COMPSCI10516
17
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 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 22COMPSCI10517
18
22.3 Binary Search Call Tree A successful search for 9: value 9 first 0 last 7 value anArray[3] value 9 first 0 last 2 value anArray[1] value 9 first 2 last 2 value anArray[2] return 2 01234567 1591215212931 index binary_search(list,0,7,9) binary_search(list,0,2,9) binary_search(list,2,2,9) 22COMPSCI10518
19
22.3 Binary Search Call Tree An unsuccessful search for 6: value 6 first 0 last 7 value anArray[3] value 6 first 0 last 2 value anArray[1] return -1 01234567 1591215212931 index binary_search(list,0,7,6) binary_search(list,0,2,6) binary_search(list,2,2,6) value 6 first 2 last 2 value anArray[2] value 6 first 2 last 1 first last return 1 binary_search(list,2,1,6) 22COMPSCI10519
20
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 Overhead associated with method calls Inherent inefficiency of some recursive algorithms Note: The recursive methods binarySearch and solveTowers are quite efficient, but the fact and rabbit are inefficient 22COMPSCI10520
21
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 Overhead associated with method calls Iterative method is more efficient Rabbit counting recursive solution 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 22COMPSCI10521
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 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 22COMPSCI10522
23
Exercise 22COMPSCI10523 Given the following: my_list = [0, 1, 2, 8, 13, 17, 19, 32, 42] Draw the call tree of binary_search(my_list,0,8,3) binary_search(my_list,0,8,13)
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.