the art of data structures recursionrsarkis/csc162/_static/lectures/recursion.pdf · what is...

77
The Art of Data Structures Recursion Richard E Sarkis CSC 162: The Art of Data Structures

Upload: others

Post on 01-Oct-2020

5 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

The Art of Data Structures Recursion

Richard E Sarkis CSC 162: The Art of Data Structures

Page 2: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Class Administrivia

Page 3: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Agenda

• To understand that complex, difficult problems that may have a simple recursive solutions

• To learn how to formulate programs recursively

• To understand and apply the three laws of recursion

• To understand recursion as a form of iteration

• To implement the recursive formulation of a problem

• To understand how recursion is implemented by a computer system

Page 4: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion

Page 5: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating
Page 6: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating
Page 7: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating
Page 8: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion

• A description of something that refers to itself is called a recursive definition

Page 9: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion

• In mathematics, recursion is frequently used

• The most common example is the factorial:

For example, 5! = 5(4)(3)(2)(1)

Page 10: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion

• In other words,

• Or

• This definition says that 0! is 1, while the factorial of any other number is that number times the factorial of one less than that number

n! = n(n � 1)!

n! =

�1 if n = 0n(n � 1)! otherwise

Page 11: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion

• Our definition is recursive, but definitely not circular.

Consider 4!

• 4! = 4(4-1)! = 4(3!)

• What is 3!? We apply the definition again

4! = 4(3!) = 4[3(3-1)!] = 4(3)(2!)

4! = 4(3!) = 4(3)(2!) = 4(3)(2)(1!) = 4(3)(2)(1)(0!) = 4(3)(2)(1)(1) = 24

Page 12: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion

• Factorial is not circular because we eventually get

to 0!, whose definition does not rely on the

definition of factorial and is just 1

• This is called a base case for the recursion

• When the base case is encountered, we get a closed expression that can be directly (often, trivially) computed

Page 13: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Numbers Sum

• Suppose that you want to calculate the sum of a list of number, e.g. [1, 3, 5, 7, 9]

Page 14: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Numbers Sum: Iterative

def list_sum(num_list): the_sum = 0 for i in num_list: the_sum = the_sum + i return the_sum

print(list_sum([1,3,5,7,9]))

Page 15: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Numbers Sum

• total = (1+(3+(5+(7+9)))) total = (1+(3+(5+16))) total = (1+(3+21)) total = (1 + 24) total = 25

• listSum(numList) = first(numList) + listSum(rest(numList))

Page 16: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Numbers Sum: Recursive

def list_sum_rec(num_list): if len(num_list) == 1: return num_list[0] else: return num_list[0] + list_sum_rec(num_list[1:])

print(list_sum_rec([1,3,5,7,9]))

Page 17: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion

• This is inefficient (lots of copying), but Python runs out of stack to keep track of the calls before the cost gets out of hand

• Note that the two implementations actually sum the elements in opposite order

• We could make them do it in the same order like this:

Page 18: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Numbers Sum: Recursive (better)

def listsum_rec2(the_sum, l): if len(l) == 0: return the_sum return listsum_rec2(the_sum + l[0], l[1:])

print(listsum_rec2(0, [1,3,5,7,9]))

Page 19: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion The Recursive Sum Function

def helper(sum, l): if len(l) == 0: return sum return helper(sum + l[0], l[1:])

def listsum_rec3(l): return helper(0, l)

Page 20: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Recursive Calls Adding a List of Numbers

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Calculating the Sum of a List of NumbersThe Three Laws of RecursionConverting an Integer to a String in Any Base

Series of Recursive Calls Adding a List of Numbers

sum(1,3,5,7,9) 1 +=

sum(3,5,7,9) 3 +=

sum(5,7,9) 5 +=

sum(7,9) 7 +=

sum(9) 9=

Recursion

Page 21: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Recursive Calls Adding a List of Numbers

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Calculating the Sum of a List of NumbersThe Three Laws of RecursionConverting an Integer to a String in Any Base

Series of Recursive Returns from Adding a List ofNumbers

sum(1,3,5,7,9) 1 + 24=

sum(3,5,7,9) 3 + 21=

sum(5,7,9) 5 + 16=

sum(7,9) 7 + 9=

sum(9) 9=

25 =

Recursion

Page 22: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion The Three Laws

1. A robot may not injure a human being or, through inaction, allow a human being to come to harm.

2. A robot must obey the orders given it by human beings except where such orders would conflict with the First Law.

3. A robot must protect its own existence as long as such protection does not conflict with the First or Second Laws.

Page 23: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Still, they're important laws.

Page 24: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion The Three Laws of…Recursion

1. A recursive algorithm must have a base case

2. A recursive algorithm must change its state and move toward the base case

3. A recursive algorithm must call itself, recursively

Page 25: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Areas of Use

• Two fundamental computational concepts

• Divide & Conquer: Solve a problem in terms of a smaller version of itself

• Backtracking: Systematically explore a set of possible solutions

Page 26: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Factorial

Page 27: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Factorial

• We’ve seen previously that fact can be calculated using a loop accumulator

• If fact is written recursively…

Page 28: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Factorial

def fact(n): if n == 0: return 1 else: return n * fact(n-1)

Page 29: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Factorial

• We’ve written a function that calls itself, a recursive function

• The function first checks to see if we’re at the base case (n==0). If so, return 1

• Otherwise, return the result of multiplying n by the factorial of n-1, fact(n-1)

Page 30: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Factorial

>>> fact(4)24>>> fact(10)3628800>>> fact(100)93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L>>>

• Remember that each call to a function starts that function anew, with its own copies of local variables and parameters

Page 31: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Factorial13.2. Recursive Problem-solving 435

n = 1

11n =

0

def fact(n): if n == 0: return 1 else: return n * fact(n1)

n:

def fact(n): if n == 0: return 1 else: return n * fact(n1)

n:2 1

def fact(n): if n == 0: return 1 else: return n * fact(n1)

n: 0

fact(5) n = 4

24

n = 3n =

5def fact(n): if n == 0: return 1 else: return n * fact(n1)

n:

def fact(n): if n == 0: return 1 else: return n * fact(n1)

n: 4

def fact(n): if n == 0: return 1 else: return n * fact(n1)

n: 3

2

120

n = 2

6

Figure 13.1: Recursive computation of 5!

13.2.3 Example: String Reversal

Python lists have a built-in method that can be used to reverse the list. Sup-pose that you want to compute the reverse of a string. One way to handle thisproblem effectively would be to convert the string into a list of characters, re-verse the list, and turn the list back into a string. Using recursion, however, wecan easily write a function that computes the reverse directly, without having todetour through a list representation.

The basic idea is to think of a string as a recursive object; a large string iscomposed out of smaller objects, which are also strings. In fact, one very handyway to divide up virtually any sequence is to think of it as a single first item thatjust happens to be followed by another sequence. In the case of a string, we candivide it up into its first character and “all the rest.” If we reverse the rest of thestring and then put the first character on the end of that, we’ll have the reverseof the whole string.

Let’s code up that algorithm and see what happens.

def reverse(s):

return reverse(s[1:]) + s[0]

Notice how this function works. The slice s[1:] gives all but the first characterof the string. We reverse the slice (recursively) and then concatenate the first

Page 32: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Fibonacci

Page 33: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Fibonacci

• Sometimes one has to be careful with recursion

• In addition to limits on stack depth [sys.setrecursionlimit(limit)], and the cost of argument copying, some naive recursive algorithms are inherently expensive

Page 34: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Fibonacci Iterative Fibonacci function – O(n)

def fib_iter(n): a = 0 b = 1 i = 0 print(a) while i < n: t = a+b a = b b = t print(a) i += 1

return a

Page 35: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Fibonacci Naive recursive version, O(2n)

def fib_rec_1(n): if n < 2: return 1 return fib_rec_1(n-1) + fib_rec1(n-2)

Page 36: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Fibonacci Good recursive version, O(n)

def fib_rec_2(n): def helper(a, b, i): if i == n: return b return helper(b, a + b, i + 1)

return helper(1, 0, 0)

Page 37: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Exercise

Page 38: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

CSC 161Prof. R Sarkis

QuizAlgorithms

University of RochesterSpring 2017

Keep your quiz until instructed to pass it forward!

Student’s Name:

Workshop Leader:

1. Take this recursive function:

1 def fun(n):2 if n == 0:3 return []45 return fun(n//2) + [n%2]67 fun(25)

(a) Identify the line number for the base case in fun(n):

(b) Identify the line number, and specific recursive call in fun(n):

(c) Use the table below to determine the output of fun(n) when it is called with n = 25 (line 7):

RecursionLevel

n fun(n) iscalled with. . .

is n == 0? line 5, calculaten//2

line 5, calculaten%2

0 (start) 25 fun(25) FALSE 12 11 122345

(d) The final returned value from calling fun(25):

Page 39: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

1 def fun(25): 2 if n == 0: 3 return [] 4 5 return fun(25//2) + [25%2]

1 def fun(12): 2 if n == 0: 3 return [] 4 5 return fun(12//2) + [12%2]

1 def fun(6): 2 if n == 0: 3 return [] 4 5 return fun(6//2) + [6%2]

1 def fun(3): 2 if n == 0: 3 return [] 4 5 return fun(3//2) + [3%2]

1 def fun(1): 2 if n == 0: 3 return [] 4 5 return fun(1//2) + [1%2]

1 def fun(0): 2 if n == 0: 3 return [] 4 5 return fun(n//2) + [n%2]

fun(25)

[]

[] + [1]

[] + [1] + [1]

[] + [1] + [1] + [0]

[] + [1] + [1] + [0] + [0] + [1]

[1,1,0,0,1]

[] + [1] + [1] + [0] + [0]

[1]

[1, 1]

[1, 1, 0]

[1, 1, 0, 0]

[1, 1, 0, 0, 1]

Page 40: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

recursion level n fun(n) is

called with… is n == 0? line 5, calc n//2

line 5, calc n%2

0 (start) 25 fun(25) FALSE 12 1

1 12 fun(12) FALSE 6 0

2 6 fun(6) FALSE 3 0

3 3 fun(3) FALSE 1 1

4 1 fun(1) FALSE 0 1

5 0 fun(0) TRUE nothing, it returns

nothing, it returns

Page 41: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Int → Str (in any base)

Page 42: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Int → Str (in any base)

• Reduce the original number to a series of single-digit numbers

• Convert the single digit-number to a string using a lookup

• Concatenate the single-digit strings together to form the final result

Page 43: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Int → Str in Base 10

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Calculating the Sum of a List of NumbersThe Three Laws of RecursionConverting an Integer to a String in Any Base

Converting an Integer to a String in Base 10

toStr(769) 769 / 10 ‘9'

toStr(76) 76 / 10 ‘6'

toStr(7) 7 < 10 ‘7'

Remainder

+

+

Recursion

Page 44: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Int → Str in Base 2–16

def to_str(n, base): convert_string = "0123456789ABCDEF"

if n < base: return convert_string[n] else: return to_str(n // base, base) + convert_string[n % base]

print(to_str(1453, 16))

Page 45: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Int → Str Decimal 10 to its Binary String

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Calculating the Sum of a List of NumbersThe Three Laws of RecursionConverting an Integer to a String in Any Base

Converting the Number 10 to its Base 2 StringRepresentation

toStr(10) 10 / 2 ‘0'

toStr(5) 5 / 2 ‘1'

toStr(2) 2 / 2 ‘0'

Remainder

toStr(1) 1 < 2 ‘1'

+

+

+

Recursion

Page 46: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Int → Str Pushing the Strings onto a Stack

r_stack = Stack()

def to_str(n, base): convert_string = "0123456789ABCDEF" if n < base: r_stack.push(convert_string[n]) else: r_stack.push(convert_string[n % base]) to_str(n // base, base)

Page 47: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Int → Str Strings Placed on the Stack

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Strings Placed on the Stack During Conversion

‘0'

‘1'

‘0'

‘1'

Recursion

Page 48: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Int → Str Call Stack: toStr(10,2)

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Call Stack Generated from toStr(10,2)

toStr(10,2) n = 10 base = 2

toStr(10/2,2) + convertString[10%2]

toStr(5,2) n = 5 base = 2

toStr(5/2,2) + convertString[5%2]

toStr(2,2) n = 5 base = 2

toStr(2/2,2) + convertString[2%2]

'1'

Recursion

Page 49: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

String Permutations Revisit Anagram Tester

Page 50: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

String Permutations Brute Force Anagram Testing

def permutation(s, prefix=""): n = len(s) if (n == 0): print(prefix) else: for i in range(n): permutation(s[0:i] + s[i+1:n], prefix + s[i])

permutation("ape")

Page 51: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Euclid's Algorithm Greatest Common Divisor (GCD)

Page 52: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Euclid's Algorithm GCD

• https://en.wikipedia.org/wiki/Greatest_common_divisor

Page 53: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Euclid's Algorithm GCD

def gcd(a, b): if b == 0: return a elif a < b: return gcd(b, a) else: return gcd(a-b, b)

Page 54: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Euclid's Algorithm GCD, Improved

def gcd(a, b): if b == 0: return a else: return gcd(b, a % b)

Page 55: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Euclid's Algorithm Extended GCD

def ext_gcd(x, y): if y == 0: return(x, 1, 0) else: (d, a, b) = ext_gcd(y, x%y) return (d, b, a-(x/y)*b)

Page 56: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Tower of HanoiSierpinski TriangleCryptography and Modular Arithmetic

Call Tree for Extended GCD Algorithm

x,y =25,9

(d,a,b) = gcd(9,7)return 1,-4,-3-25/9*4

x,y =9,7

(d,a,b) = gcd(7,2)return 1,-3,1-9/7*-3

x,y =7,2

(d,a,b) = gcd(2,1)return 1,1,0-7/2*1

x,y =2,1

(d,a,b) = gcd(1,1)return 1,0,1-2/1*0

x,y =1,1

(d,a,b) = gcd(1,0)return 1,0,1-1*0

x,y =1,0

return 1,1,0

(1,1,0)

(1,1,0)

(1,0,1)

(1,1,-3)

(1,-3,4)

(1,4,-11)

Recursion

Euclid's Algorithm Extended GCD

Page 57: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Towers of Hanoi A Complex Recursive Problem

Page 58: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Towers of Hanoi Background

• Objective: move N disks from peg A to C can be reduced to three sub problems:

1. Move N-1 disks from peg A to intermediate

peg B

2. Move the largest Disk N from peg A to target

C

3. Move the N-1 parked disks from B to C

Page 59: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Towers of Hanoi Background

• Tower of Hanoi (Wikipedia)

• Tower of Hanoi - 5 disks - 31 moves

Page 60: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Towers of Hanoi An Example Arrangement of Disks

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Tower of HanoiSierpinski TriangleCryptography and Modular Arithmetic

An Example Arrangement of Disks for the Tower ofHanoi

fromPole withPole toPole

Recursion

Page 61: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Towers of Hanoi An Example Arrangement of Disks

• Move a tower of height-1 to an intermediate pole, using the final pole

• Move the remaining disk to the final pole

• Move the tower of height-1 from the intermediate pole to the final pole using the original pole

Page 62: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Towers of Hanoi Python Code for the Tower of Hanoi

def move_tower(height, from_pole, to_pole, with_pole): if height >= 1: move_tower(height - 1, from_pole, with_pole, to_pole) move_disk(from_pole, to_pole) move_tower(height - 1, with_pole, to_pole, from_pole)

def move_disk(fp,tp): print("moving disk from",fp,"to",tp)

move_tower(3, "A", "B", "C")

Page 63: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Towers of Hanoi An Iterative Version

Interesting secret: there's also an easy iterative solution, but it isn't anywhere near as intuitive

1. On every even-numbered move (starting with zero), move the little disk one pole "clockwise" If the total number of disks is even, the first move should be from from_pole to with_pole; if the total number of disks is odd, the first move should be from from_pole to with_pole

Page 64: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Towers of Hanoi An Iterative Version

2. On every odd-numbered move, make the only legal move not involving the smallest disk (there can be only one)

Page 65: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Towers of Hanoi Python Code for the Tower of Hanoi

def hanoi_iter(height, fromPole, toPole, withPole): if height % 2 == 0: poles = [fromPole, withPole, toPole] else: poles = [fromPole, toPole, withPole] stacks = [range(height, 0, -1), [height], [height]] for i in range(2**height-1): if i % 2 == 0: # move little disk fd = (i//2)%3 td = (i//2+1)%3 else: # move other disk fd = (i//2)%3 td = (i//2+2)%3 if (stacks[fd][len(stacks[fd])-1] > stacks[td][len(stacks[td])-1]): td = (i//2)%3 fd = (i//2+2)%3 stacks[td].append(list(stacks[fd]).pop()) move_disk(poles[fd], poles[td])

Page 66: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

The Sierpinski Triangle A Complex Recursive Problem

Page 67: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Sierpinski Triangle Background

• Sierpinski triangle (Wikipedia)

Page 68: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Sierpinski Triangle The Sierpinski Triangle

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Tower of HanoiSierpinski TriangleCryptography and Modular Arithmetic

The Sierpinski Triangle

Recursion

Page 69: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Sierpinski Triangle Python Code

import turtle

def draw_triangle(points, color, my_turtle): my_turtle.fillcolor(color) my_turtle.up() my_turtle.goto(points[0][0],points[0][1]) my_turtle.down() my_turtle.begin_fill() my_turtle.goto(points[1][0], points[1][1]) my_turtle.goto(points[2][0], points[2][1]) my_turtle.goto(points[0][0], points[0][1]) my_turtle.end_fill()

def get_mid(p1, p2): return ((p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2)

Page 70: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Sierpinski Triangle Python Code

def sierpinski(points, degree, my_turtle): color_map = ['blue', 'red', 'green', 'white', 'yellow', 'violet', 'orange'] draw_triangle(points, color_map[degree], my_turtle) if degree > 0: sierpinski([points[0], get_mid(points[0], points[1]), get_mid(points[0], points[2])], degree-1, my_turtle) sierpinski([points[1], get_mid(points[0], points[1]), get_mid(points[1], points[2])], degree-1, my_turtle) sierpinski([points[2], get_mid(points[2], points[1]), get_mid(points[0], points[2])], degree-1, my_turtle)

Page 71: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Sierpinski Triangle Python Code

def main(): my_turtle = turtle.Turtle() my_win = turtle.Screen() my_points = [[-100, -50], [0, 100], [100, -50]] sierpinski(my_points, 3, my_turtle) my_win.exitonclick()

Page 72: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Sierpinski Triangle

ObjectivesWhat Is Recursion?

Stack Frames: Implementing RecursionComplex Recursive Problems

Summary

Tower of HanoiSierpinski TriangleCryptography and Modular Arithmetic

Building a Sierpinski Triangle

left top right

left top right

left top right

Recursion

Page 73: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Summary

Page 74: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Summary

• All recursive algorithms must have a base case

• A recursive algorithm must change its state and make progress toward the base case

• A recursive algorithm must call itself (recursively); Recursion can take the place of iteration in some cases

Page 75: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Summary

• Recursive algorithms often map very naturally to a formal expression of the problem you are trying to solve

Page 76: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Recursion Summary

• Recursion doesn't have to be any more expensive than iteration (though it is in Python)

• It's definitely more expressive: iteration can't capture recursion in the general case without an explicit stack

Page 77: The Art of Data Structures Recursionrsarkis/csc162/_static/lectures/Recursion.pdf · What Is Recursion? Stack Frames: Implementing Recursion Complex Recursive Problems Summary Calculating

Questions?