15-112 Fundamentals of Programming Week 5 - Lecture 2: Recursion - - PowerPoint PPT Presentation

15 112 fundamentals of programming
SMART_READER_LITE
LIVE PREVIEW

15-112 Fundamentals of Programming Week 5 - Lecture 2: Recursion - - PowerPoint PPT Presentation

15-112 Fundamentals of Programming Week 5 - Lecture 2: Recursion June 14, 2016 What is recursion? Recursion: To understand recursion, you have to first understand recursion. What is recursion? Recursion: To understand recursion, you have


slide-1
SLIDE 1

15-112 Fundamentals of Programming

Week 5 - Lecture 2: Recursion

June 14, 2016

slide-2
SLIDE 2

What is recursion?

To understand recursion, you have to first understand recursion. Recursion:

slide-3
SLIDE 3

What is recursion?

To understand recursion, you have to first understand recursion. Recursion:

slide-4
SLIDE 4

What is recursion?

To understand recursion, you have to first understand recursion. Recursion: Not making progress. Let’s ask Google.

slide-5
SLIDE 5

What is recursion?

Let’s see what my dictionary says.

slide-6
SLIDE 6

What is recursion?

recursion (n): See recursion

slide-7
SLIDE 7

What is recursion in programming?

We say that a function is recursive if at some point, it calls itself.

def test(): test()

Can we do something more meaningful? Warning: Recursion can be weird and counter-intuitive at first!

slide-8
SLIDE 8

Motivation: break a problem into smaller parts

Example: Figuring out if a given password is secure.

  • Is string length at least 10?
  • Does the string contain an upper-case letter?
  • Does the string contain a lower-case letter?
  • Does the string contain a number?
slide-9
SLIDE 9

Motivation: break a problem into smaller parts

isSecurePassword length upper lower number merge results True or False input

slide-10
SLIDE 10

Motivation: break a problem into smaller parts

Recursion: The smaller problems are not different. They are smaller versions of the original problem. The problem is split into smaller but different problems. isSecurePassword:

slide-11
SLIDE 11

Recursion Example: Sorting

Sorting the midterms by name. Divide the pile in half. Sort the first half. Sort the second half. Merge the sorted piles. Sort:

slide-12
SLIDE 12

Recursion Example: Sorting

sort sort first half merge results input list sort second half

slide-13
SLIDE 13

Recursion Example: Sorting

Divide the pile in half. Sort the first half. Sort the second half. Merge the sorted piles. Sort: What if my pile consists of just a single exam?

slide-14
SLIDE 14

Recursion Example: Sorting

Sort: If the pile consists of one element, do nothing. Else: Divide the pile in half. Sort the first half. Sort the second half. Merge the sorted piles.

slide-15
SLIDE 15

Recursion Example: Sorting

def sort(a): if (len(a) <= 1): return a leftHalf = a[0 : len(a)//2] rightHalf = a[len(a)//2 : len(a)] return merge(sort(leftHalf), sort(rightHalf)) def merge(a, b): # We have already seen this.

This works! And it is called merge sort.

slide-16
SLIDE 16

Recursion Example: Sorting

[ 1, 5, 8, 3, 7, 2, 4, 6 ] [ 1, 5, 8, 3 ] [ 7, 2, 4, 6 ] [ 1, 3, 5, 8 ]

sort

[ 2, 4, 6, 7 ]

sort

[ 1, 2, 3, 4, 5, 6, 7, 8 ]

merge

slide-17
SLIDE 17

Recursion Example: Sorting

[ 1, 5, 8, 3, 7, 2, 4, 6 ] [ 1, 5, 8, 3 ] [ 7, 2, 4, 6 ] [ 1, 5 ] [ 8, 3 ] [ 1 ] [ 5 ] [ 8 ] [ 3 ] [ 7 ] [ 2 ] [ 4 ] [ 6 ] [ 7, 2 ] [ 4, 6 ] [ 1, 5 ] [ 3, 8 ] [ 2, 7 ] [ 4, 6 ] [ 1, 3, 5, 8 ] [ 2, 4, 6, 7 ] [1, 2, 3, 4, 5, 6, 7, 8 ]

slide-18
SLIDE 18

To understand how recursion works, let’s look at simpler examples.

slide-19
SLIDE 19

Simple Example: Factorial

1! = 1 2! = 2 x 1 3! = 3 x 2 x 1 4! = 4 x 3 x 2 x 1 5! = 5 x 4 x 3 x 2 x 1 ... n! = n x (n-1) x (n-2) x ... x 1 n factorial is the product of integers from 1 to n.

slide-20
SLIDE 20

Simple Example: Factorial

Finding the recursive structure in factorial: Can we express n! using a smaller factorial ? n! = n x (n - 1) x (n - 2) x ... x 1

slide-21
SLIDE 21

Simple Example: Factorial

Finding the recursive structure in factorial: Can we express n! using a smaller factorial ? n! = n x (n - 1) x (n - 2) x ... x 1 (n-1)! n! = n x (n - 1)!

slide-22
SLIDE 22

Simple Example: Factorial

def factorial(n): return n * factorial(n - 1)

“Unwinding” the code when n = 4:

factorial(4) 4 * factorial(3) 3 * factorial(2) 2 * factorial(1) 1 * factorial(0) 0 * factorial(-1)

... No stopping condition

slide-23
SLIDE 23

Simple Example: Factorial

def factorial(n): if (n == 1): return 1 else: return n * factorial(n - 1) factorial(4) 4 * factorial(3) 3 * factorial(2) 2 * factorial(1) 1

slide-24
SLIDE 24

Simple Example: Factorial

factorial(4) 4 * factorial(3) 3 * factorial(2) 2 * 1 def factorial(n): if (n == 1): return 1 else: return n * factorial(n - 1)

slide-25
SLIDE 25

Simple Example: Factorial

factorial(4) 4 * factorial(3) 3 * 2 def factorial(n): if (n == 1): return 1 else: return n * factorial(n - 1)

slide-26
SLIDE 26

Simple Example: Factorial

factorial(4) 4 * 6

evaluates to 24

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

slide-27
SLIDE 27

Simple Example: Factorial

factorial(4) 4 * 6

evaluates to 24

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

Recursive calls make their way down to the base case. The solution is then built up from base case.

slide-28
SLIDE 28

Simple Example: Factorial

def factorial(n): if (n == 1): return 1 else: return n * factorial(n - 1) factorial(4) 4 * factorial(3) 3 * factorial(2) 2 * factorial(1) 1

Call Stack depth 0 depth 1 depth 2 depth 3

slide-29
SLIDE 29

Simple Example: Factorial

def factorial(n): if (n == 1): return 1 else: return n * factorial(n - 1) factorial(4) 4 * factorial(3) 3 * factorial(2) 2 * factorial(1) 1

Call Stack depth 0 depth 1 depth 2 depth 3 Independent!

slide-30
SLIDE 30

Simple Example: Factorial

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

Another way of convincing ourselves it works:

Does factorial(1) work (base case) ? Does factorial(2) work ? returns 2*factorial(1) Does factorial(3) work ? returns 3*factorial(2) Does factorial(4) work ? returns 4*factorial(3)

slide-31
SLIDE 31

How recursion works

fac(1) —> fac(2) —> fac(3) —> fac(4) —> ... fac(1) fac(2) fac(3) fac(4) . . .

slide-32
SLIDE 32

2 important properties of recursive functions

There should be a base case (a case which does not make a recursive call) The recursive call(s) should make progress towards the base case.

  • 1. “Base case”
  • 2. “Progress”
slide-33
SLIDE 33

Simple Example: Factorial

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

slide-34
SLIDE 34

Simple Example: Factorial

Base case

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

slide-35
SLIDE 35

Simple Example: Factorial

Making progress towards base case

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

slide-36
SLIDE 36

Another example: Fibonacci

Fibonacci Sequence: 1 1 2 3 5 8 13 21 ...

def fib(n): if (n == 0): return 1 else: return fib(n-1) + fib(n-2)

What happens when we call fib(1) ?

slide-37
SLIDE 37

Another example: Fibonacci

Fibonacci Sequence: 1 1 2 3 5 8 13 21 ...

def fib(n): if (n == 0 or n == 1): return 1 else: return fib(n-1) + fib(n-2)

slide-38
SLIDE 38

Another example: Fibonacci

Fibonacci Sequence: 1 1 2 3 5 8 13 21 ... Base case

def fib(n): if (n == 0 or n == 1): return 1 else: return fib(n-1) + fib(n-2)

slide-39
SLIDE 39

Another example: Fibonacci

Fibonacci Sequence: 1 1 2 3 5 8 13 21 ... Each recursive call makes progress towards the base case (and doesn’t skip it!!!)

def fib(n): if (n == 0 or n == 1): return 1 else: return fib(n-1) + fib(n-2)

slide-40
SLIDE 40

Unwinding the code

fib(4)

slide-41
SLIDE 41

Unwinding the code

fib(4) fib(3) + fib(2)

slide-42
SLIDE 42

Unwinding the code

fib(4) fib(3) + fib(2) fib(2) + fib(1)

slide-43
SLIDE 43

Unwinding the code

fib(4) fib(3) + fib(2) fib(2) + fib(1) fib(1) + fib(0)

slide-44
SLIDE 44

Unwinding the code

fib(4) fib(3) + fib(2) fib(2) + fib(1) 1 + 1

slide-45
SLIDE 45

Unwinding the code

fib(4) fib(3) + fib(2) 2 + fib(1)

slide-46
SLIDE 46

Unwinding the code

fib(4) fib(3) + fib(2) 2 + 1

slide-47
SLIDE 47

Unwinding the code

fib(4) 3 + fib(2)

slide-48
SLIDE 48

Unwinding the code

fib(4) 3 + fib(2) fib(1) + fib(0)

slide-49
SLIDE 49

Unwinding the code

fib(4) 3 + fib(2) 1 + fib(0)

slide-50
SLIDE 50

Unwinding the code

fib(4) 3 + fib(2) 1 + 1

slide-51
SLIDE 51

Unwinding the code

fib(4) 3 + 2

slide-52
SLIDE 52

Unwinding the code

5

slide-53
SLIDE 53

Recursion

fib(0), fib(1) —> fib(2) —> fib(3) —> fib(4) —> ... fib(0) fib(1) fib(2)fib(3) . . .

slide-54
SLIDE 54

The sweet thing about recursion

Do these 2 steps:

  • 1. Base case:

Solve the “smallest” version of the problem (with no recursion).

  • 2. Recursive call(s):

Correctly write the solution to the problem in terms of “smaller” version(s) of the same problem. Your recursive function will always work!

slide-55
SLIDE 55

Unwinding vs Trusting

Over time, you will start trusting recursion. This trust is very important! Unwinding recursive functions:

  • OK at first (for simple examples)
  • Not OK once you understand the logic

Recursion will earn your trust.

slide-56
SLIDE 56

Unwinding vs Trusting

def fib(n): if (n == 0 or n == 1): return 1 else: return fib(n-1) + fib(n-2)

You have to trust these will return the correct answer. This is why recursion is so powerful. You can assume every subproblem is solved for free!

slide-57
SLIDE 57

Getting comfortable with recursion

  • 1. See lot’s of examples
  • 2. Practice yourself
slide-58
SLIDE 58

Getting comfortable with recursion

  • 1. See lot’s of examples
slide-59
SLIDE 59

Recursive function design

Ask yourself: If I had the solutions to the smaller instances for free, how could I solve the original problem? Handle the base case: A small version of the problem that does not require recursive calls. Double check: All your recursive calls make progress towards the base case(s) and they don’t miss it. Write the recursive relation: e.g. fib(n) = fib(n-1) + fib(n-2)

slide-60
SLIDE 60

Examples

slide-61
SLIDE 61

Example: sum

Write a function that takes an integer n as input, and returns the sum of all numbers from 1 to n.

sum(n) = n + (n-1) + (n-2) + (n-3) + ... + 3 + 2 + 1

slide-62
SLIDE 62

Example: sum

Write a function that takes an integer n as input, and returns the sum of all numbers from 1 to n.

sum(n) = n + (n-1) + (n-2) + (n-3) + ... + 3 + 2 + 1 sum(n-1) sum(n) = n +

slide-63
SLIDE 63

Example: sum

Write a function that takes an integer n as input, and returns the sum of all numbers from 1 to n.

def sum(n): if (n == 0): return 0 else: return n + sum(n-1)

slide-64
SLIDE 64

Example: sum in range

Write a function that takes integers n and m as input (n <= m), and returns the sum of all numbers from n to m.

sum(n, m) = n + (n+1) + (n+2) + ... + (m-1) + m

slide-65
SLIDE 65

Example: sum in range

Write a function that takes integers n and m as input (n <= m), and returns the sum of all numbers from n to m.

sum(n, m) = n + (n+1) + (n+2) + ... + (m-1) + m sum(n, m-1) sum(n, m) = + m

slide-66
SLIDE 66

Example: sum in range

Write a function that takes integers n and m as input (n <= m), and returns the sum of all numbers from n to m.

sum(n, m) = n + (n+1) + (n+2) + ... + (m-1) + m sum(n+1, m)

slide-67
SLIDE 67

Example: sum in range

Write a function that takes integers n and m as input (n <= m), and returns the sum of all numbers from n to m.

sum(n, m) = n + (n+1) + (n+2) + ... + (m-1) + m sum(n+1, m) sum(n, m) = n +

slide-68
SLIDE 68

Example: sum in range

Write a function that takes integers n and m as input (n <= m), and returns the sum of all numbers from n to m.

def sum(n, m): if (n == m): return n else: return n + sum(n+1, m)

slide-69
SLIDE 69

Note: objects with recursive structure

Problems related to these objects often have very natural recursive solutions. Lists 8 1 2 4 5 5 6 9 9 Strings (a list of characters)

“Dammit I’m mad”

slide-70
SLIDE 70

Example: sumList(L)

Write a function that takes a list of integers as input and returns the sum of all the elements in the list. 3 5 2 6 9 1 5

sum( ) =

3 5 2 6 9 1 5

3 + sum( )

5 2 6 9 1 5

slide-71
SLIDE 71

Example: sumList(L)

def sum(L): if (len(L) == 0): return 0 else: return L[0] + sum(L[1:])

Write a function that takes a list of integers as input and returns the sum of all the elements in the list.

slide-72
SLIDE 72

Example: isElement(L, e)

Write a function that checks if a given element is in a given list. 3 5 2 6 9 1 5 6

slide-73
SLIDE 73

Example: isElement(L, e)

Write a function that checks if a given element is in a given list. 3 5 2 6 9 1 5 6

slide-74
SLIDE 74

Example: isElement(L, e)

Write a function that checks if a given element is in a given list.

def isElement(L, e): else: return isElement(L[1:], e) else: if (L[0] == e): return True if (len(L) == 0): return False

This is linear search.

slide-75
SLIDE 75

Example: isPalindrome(s)

Write a function that checks if a given string is a palindrome. h a n n a h

slide-76
SLIDE 76

Example: isPalindrome(s)

Write a function that checks if a given string is a palindrome. h a n n a h

should be palindrome

slide-77
SLIDE 77

Example: isPalindrome(s)

Write a function that checks if a given string is a palindrome.

def isPalindrome(s): else: return (s[0] == s[len(s)-1] and isPalindrome(s[1:len(s)-1])) if (len(s) <= 1): return True

slide-78
SLIDE 78

Example: reverse array

3 5 2 6 9 1 5

swap

Write a (non-destructive) function that reverses the elements of a list. e.g. [1, 2, 3, 4] becomes [4, 3, 2, 1]

slide-79
SLIDE 79

Example: reverse array

5 5 2 6 9 1 3

reverse the middle

Write a (non-destructive) function that reverses the elements of a list. e.g. [1, 2, 3, 4] becomes [4, 3, 2, 1]

slide-80
SLIDE 80

Example: reverse array

def reverse(a): if (len(a) == 0 or len(a) == 1): return a else: return [a[-1]] + reverse(a[1:len(a)-1]) + [a[0]]

Write a (non-destructive) function that reverses the elements of a list. e.g. [1, 2, 3, 4] becomes [4, 3, 2, 1]

slide-81
SLIDE 81

Example: findMax(L)

3 5 2 6 9 1 5 Write a function that finds the maximum value in a list.

slide-82
SLIDE 82

Example: findMax(L)

3 5 2 6 9 1 5

findMax then compare it with 3

Write a function that finds the maximum value in a list.

slide-83
SLIDE 83

Example: findMax(L)

def findMax(L): if (len(L) == 1): return L[0] m = findMax(L[1:]) else: if (L[0] < m): return m else: return L[0]

Write a function that finds the maximum value in a list. if L = [ ], return None

slide-84
SLIDE 84

Example: binary search

Write a function for binary search: find an element in a sorted list. 8 1 2 4 5 5 6 9 9 50 99 60 50

slide-85
SLIDE 85

Example: binary search

8 1 2 4 5 5 6 9 9 50 99 60 50 Write a function for binary search: find an element in a sorted list.

slide-86
SLIDE 86

Example: binary search

Write a function for binary search: find an element in a sorted list.

Slicing too expensive here.

def binarySearch(a, element): if (len(a) == 0): return False mid = (start+end)//2 if (a[mid] == element): return True elif (element < a[mid]): return binarySearch(a[:mid], element) else: return binarySearch(a[mid+1:], element)

slide-87
SLIDE 87

Example: binary search

def binarySearch(a, element, start, end): if (start >= end): return False mid = (start+end)//2 if (a[mid] == element): return True elif (element < a[mid]): return binarySearch(a, element, start, mid) else: return binarySearch(a, element, mid+1, end)

slide-88
SLIDE 88

Example: findMax(L)

def findMax(L, start=0): if (start >= len(L)): return None m = findMax(L, start+1) else: if (L[start] < m): return m else: return L[start]

Write a function that finds the maximum value in a list.

elif (start == len(L)-1): return L[-1]

slide-89
SLIDE 89

Common recursive strategies

With lists and strings, 2 common strategies: Strategy 1:

  • Separate first or last index
  • Use recursion on the remaining part

Strategy 2:

  • Divide list or string in half
  • Use recursion on each half, combine results.

(or ignore one of the halves like in binary search)

slide-90
SLIDE 90

One more example to really appreciate recursion

slide-91
SLIDE 91

Example: Towers of Hanoi

Classic ancient problem: N rings in increasing sizes. 3 poles. Rings start stacked on Pole 1. Goal: Move rings so they are stacked on Pole 3.

  • Can only move one ring at a time.
  • Can’t put larger ring on top of a smaller ring.
slide-92
SLIDE 92

Example: Towers of Hanoi

slide-93
SLIDE 93

Example: Towers of Hanoi

Write a function that solves the Towers of Hanoi problem (i.e. moves the N rings from source to destination) by printing all the moves. move (N, source, destination) move (3, 1, 3):

Move ring from Pole 1 to Pole 3 Move ring from Pole 1 to Pole 2 Move ring from Pole 3 to Pole 2 Move ring from Pole 1 to Pole 3 Move ring from Pole 2 to Pole 1 Move ring from Pole 2 to Pole 3 Move ring from Pole 1 to Pole 3 (integer inputs)

slide-94
SLIDE 94

Example: Towers of Hanoi

The power of recursion: Can assume we can solve smaller instances of the problem for free. 1 2 3

slide-95
SLIDE 95

Example: Towers of Hanoi

The power of recursion: Can assume we can solve smaller instances of the problem for free.

  • Move N-1 rings from Pole 1 to Pole 2.

1 2 3

slide-96
SLIDE 96

Example: Towers of Hanoi

The power of recursion: Can assume we can solve smaller instances of the problem for free.

  • Move N-1 rings from Pole 1 to Pole 2.

1 2 3

slide-97
SLIDE 97

Example: Towers of Hanoi

The power of recursion: Can assume we can solve smaller instances of the problem for free.

  • Move ring from Pole 1 to Pole 3.

1 2 3

  • Move N-1 rings from Pole 1 to Pole 2.
slide-98
SLIDE 98

Example: Towers of Hanoi

The power of recursion: Can assume we can solve smaller instances of the problem for free. 1 2 3

  • Move N-1 rings from Pole 1 to Pole 2.
  • Move ring from Pole 1 to Pole 3.
slide-99
SLIDE 99

Example: Towers of Hanoi

The power of recursion: Can assume we can solve smaller instances of the problem for free.

  • Move N-1 rings from Pole 2 to Pole 3.

1 2 3

  • Move N-1 rings from Pole 1 to Pole 2.
  • Move ring from Pole 1 to Pole 3.
slide-100
SLIDE 100

Example: Towers of Hanoi

The power of recursion: Can assume we can solve smaller instances of the problem for free. 1 2 3

  • Move N-1 rings from Pole 1 to Pole 2.
  • Move N-1 rings from Pole 2 to Pole 3.
  • Move ring from Pole 1 to Pole 3.
slide-101
SLIDE 101

Example: Towers of Hanoi

move (N, source, destination): if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from Pole ” + source + “ to Pole ” + destination) move(N-1, temp, destination) Challenge: Write the same program using loops

slide-102
SLIDE 102

How/Why it works

move (N, source, dest): if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination)

slide-103
SLIDE 103

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-104
SLIDE 104

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-105
SLIDE 105

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-106
SLIDE 106

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-107
SLIDE 107

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-108
SLIDE 108

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-109
SLIDE 109

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-110
SLIDE 110

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-111
SLIDE 111

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-112
SLIDE 112

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-113
SLIDE 113

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-114
SLIDE 114

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-115
SLIDE 115

How/Why it works

if(N > 0): Let temp be the index of other pole. move(N-1, source, temp) print (“Move ring from pole ” + source + “ to pole ” + dest) move(N-1, temp, destination) move (N, source, dest):

slide-116
SLIDE 116

How/Why it works

move(1)

. . .

move(2) move(3)

slide-117
SLIDE 117

Getting comfortable with recursion

  • 1. See lot’s of examples
  • 2. Practice yourself
slide-118
SLIDE 118

Getting comfortable with recursion

  • 2. Practice yourself