Download presentation
Presentation is loading. Please wait.
1
Module 6: Recursion Ron K. Cytron
* Department of Computer Science and Engineering Washington University in Saint Louis Thanks to Alan Waldman for comments that improved these slides * Title slide Prepared for 2u Semester Online Copyright Ron K. Cytron 2013
2
The material we study here involves no new syntax
6.0 Introduction Monolog 0 The material we study here involves no new syntax Instead, we will be analyzing and writing methods, such as we studied in Module 5 We have seen methods calling other methods Compute the distance between two points We need the sqrt method Multiplication (pedagogical example) mpy(c,d) calls add(a,b) Now we examine methods that call themselves Seems impossible to solve problem P using P But it works under the right circumstances And is a very powerful technique
3
Why study recursion? Could we live without knowing recursion?
6.0 Introduction Monolog 0 Why study recursion? Could we live without knowing recursion? Yes: with arrays, iteration, and choice, we know enough to solve any problem that can be solved on a computer. Mechanisms that allow us to write "any program" are called Turing-complete However, recursion is a powerful technique for specifying computation Mathematically satisfying And some computations are more naturally specified using recursion
4
Nature offers many examples of recursion
6.0 Introduction Nature offers many examples of recursion A tree grows its branches by applying the same pattern "in the small" as it does "in the large Shapes manipulated recursively yield interesting results From Sedgewick's book
5
Reproductive Parts M. C. Escher, 1948
6.0 Introduction Nature offers many examples of recursion But recursion sometimes seems to do the impossible 5 minutes Reproductive Parts M. C. Escher, 1948 End of Monologue
6
Some formula are explicitly recursive
6.1 Explicit recursion Oyster 1 Some formula are explicitly recursive factorial(n) = n * factorial(n-1), if n > 0 factorial(n) = 1, otherwise
7
Some formula are explicitly recursive
6.1 Explicit recursion Some formula are explicitly recursive factorial(n) = n * factorial(n-1), if n > 0 factorial(n) = 1, otherwise This works because a larger problem factorial(n)
8
Some formula are explicitly recursive
6.1 Explicit recursion Some formula are explicitly recursive factorial(n) = n * factorial(n-1), if n > 0 factorial(n) = 1, otherwise This works because a larger problem factorial(n) is phrased in terms of a smaller problem factorial(n-1)
9
Some formula are explicitly recursive
6.1 Explicit recursion Some formula are explicitly recursive factorial(n) = n * factorial(n-1), if n > 0 factorial(n) = 1, otherwise This works because a larger problem factorial(n) is phrased in terms of a smaller problem factorial(n-1) and because the computation bottoms out with a base case factorial(0) = 1
10
Some formula are explicitly recursive
6.1 Explicit recursion Some formula are explicitly recursive factorial(n) = n * factorial(n-1), if n > 0 factorial(n) = 1, otherwise This is the standard way such formulae are defined in math
11
Some formula are explicitly recursive
6.1 Explicit recursion Some formula are explicitly recursive factorial(n) = 1, if n <= 0 factorial(n) = n * factorial(n-1), otherwise Rewrote the definition to put the base case first Common in computer science
12
Some formula are explicitly recursive
6.1 Explicit recursion Some formula are explicitly recursive factorial(n) = 1, if n <= 0 factorial(n) = n * factorial(n-1), otherwise These are simply transcribed into recursive functions public static int factorial(int n) { if (n <= 0) return 1; else return n * factorial(n-1); }
13
6.1 Explicit recursion This looks like ordinary code using methods The only difference is that the method calls itself Let's look at the structure of a recursive method in more detail public static int factorial(int n) { if (n <= 0) return 1; else return n * factorial(n-1); }
14
6.1 Explicit recursion public static int factorial(int n) { if (n <= 0) return 1; else return n * factorial(n-1); } recursive call
15
6.1 Explicit recursion public static int factorial(int n) { if (n <= 0) return 1; else return n * factorial(n-1); } base case 5 minutes End of Oyster
16
Point students to their repo for the upcoming exercise
6.2a Exercise BLT 2a public Video intro Implement the factorial function Write unit tests Debugger and tracing through the code Point students to their repo for the upcoming exercise Video intro: 5 minutes, using screenflow
17
6.2a Exercise Question card Implement and test You do the same for:
sum(n) = sum(n-1) + n, if n > 0 sum(n) = 0, otherwise In your code, identify (make comments on) Recursive call Base case Implement and test This could take students 10 minutes to complete
18
6.2 Exercise Video response Show solution End of BLT
Response: 6 minutes, using screenflow End of BLT
19
Same setup as previous BLT so this can be a short video intro
6.2b Exercise BLT 2b public Same setup as previous BLT so this can be a short video intro Insist students look at each others' work before continuing (is this possible?) 1 minute intro, no screenflow needed
20
Under what circumstances does your method work?
6.2b Exercise Question card Now do the same for: add(x,y) = x, if y == 0 add(x,y) = add(x+1, y-1), otherwise In your code, identify (make comments on) Recursive call Base case Implement and test Under what circumstances does your method work? How could you generalize it to work for any x and y? Some 15 minutes for students to do this work
21
6.2b Exercise Video response Show solution End of BLT
Response: 6 minutes, using screenflow End of BLT
22
6.3 Finding recursive substructure
Oyster 3 Sometimes, we have to find the recursion in a problem It's not explicitly stated This is harder, but more like solving a puzzle Requires a bit of faith and vision Trust that a method does what we want it to do See the problem in terms of its simplest subproblem
23
6.3 Finding recursive substructure
Example sum(n) = … + n Think of the sum(n) function as a generator of the expression you see on the right sum … +
24
6.3 Finding recursive substructure
Example sum(n) = … + n Think of the sum(n) function as a generator of the expression you see on the right Believe that sum(n) really generates such an expression sum(4) = sum … +
25
6.3 Finding recursive substructure
Example sum(n) = … + n Think of the sum(n) function as a generator of the expression you see on the right Believe that sum(n) really generates such an expression sum(4) = sum(x) = … + (x-1) + x sum … +
26
6.3 Finding recursive substructure
Example sum(n) = … + n Think of the sum(n) function as a generator of the expression you see on the right Believe that sum(n) really generates such an expression sum(4) = sum(x) = … + (x-1) + x sum(x+9) = … + x + (x+1) + … + (x+8) + (x+9) sum … +
27
6.3 Finding recursive substructure
Example sum(n) = … + n Think of the sum(n) function as a generator of the expression you see on the right Believe that sum(n) really generates such an expression sum(4) = Where in this expression do we see a smaller example of the expression itself? sum … +
28
6.3 Finding recursive substructure
Example sum(n) = … + n Think of the sum(n) function as a generator of the expression you see on the right Believe that sum(n) really generates such an expression sum(4) = Where in this expression do we see a smaller example of the expression itself? sum … +
29
6.3 Finding recursive substructure
Example sum(n) = … + n Think of the sum(n) function as a generator of the expression you see on the right Believe that sum(n) really generates such an expression sum(4) = sum(3) = Where in this expression do we see a smaller example of the expression itself? sum … +
30
6.3 Finding recursive substructure
Example sum(n) = … + n Think of the sum(n) function as a generator of the expression you see on the right Believe that sum(n) really generates such an expression sum(4) = sum(3) = sum(4) = sum(3) Where in this expression do we see a smaller example of the expression itself? sum … +
31
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n
32
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n sum(n) = … (n-1) n
33
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n sum(n) = … (n-1) n Aha, the boxed portion also looks like sum(something), but sum of what?
34
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n sum(n) = … (n-1) n sum(n-1) if we believe sum(x) really generates … + x
35
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n sum(n) = sum(n-1) n sum(n-1) if we believe sum(x) really generates … + x
36
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n sum(n) = sum(n-1) n Now we have an explicitly recursive formula.
37
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n sum(n) = sum(n-1) n sum(?) = ? Now we have an explicitly recursive formula. But it is missing a base case. What is the smallest example of sum(n)?
38
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n sum(n) = sum(n-1) n sum(0) = 0 Now we have an explicitly recursive formula. But it is missing a base case. What is the smallest example of sum(n)?
39
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n Leads to sum(n) = 0, if n == 0 sum(n) = sum(n-1) + n, otherwise
40
6.3 Finding recursive substructure
Where is the recursive substructure? sum(n) = … + n Leads to sum(n) = 0, if n == 0 sum(n) = sum(n-1) + n, otherwise private static int sum(int n) { if (n == 0) return 0; else return sum(n-1) + n; }
41
6.3 Finding recursive substructure
Why does the following substructure not work? sum(n) = … + n sum(n) = … (n-1) n
42
6.3 Finding recursive substructure
Why does the following substructure not work? sum(n) = … + n sum(n) = … (n-1) n Boxed expression is sum(n) - 0
43
6.3 Finding recursive substructure
Why does the following substructure not work? sum(n) = … + n sum(n) = … (n-1) n Leads to: sum(n) = 0 + sum(n) - 0
44
6.3 Finding recursive substructure
Why does the following substructure not work? sum(n) = … + n sum(n) = … (n-1) n Leads to: sum(n) = 0 + sum(n) – 0 This is true, mathematically
45
6.3 Finding recursive substructure
Why does the following substructure not work? sum(n) = … + n sum(n) = … (n-1) n Leads to: sum(n) = 0 + sum(n) – 0 This is true, mathematically But it does not lead to a simpler use of the sum function
46
6.3 Finding recursive substructure
Why does the following substructure not work? sum(n) = … + n sum(n) = … (n-1) n Leads to: sum(n) = 0 + sum(n) – 0 This is true, mathematically But it does not lead to a simpler use of the sum function
47
6.3 Finding recursive substructure
To work, we must find a smaller instance of the function One that seems easier to compute One that points us toward the base case sum(n) = … + n sum(n) = … (n-1) n 15 minutes End of Oyster
48
6.3a Visual recursion and base cases
BLT 3a public Video intro: about 3 minutes Amazing hand-drawn image in NY Times by Serkan Ozkaya [Serkan Ozkaya] simply wanted to draw and see printed a faithful copy of all the type and pictures planned for a broadsheet page of this newspaper: this very page you are reading right now, which shows his version of the page you are reading right now, which shows his version of his version of the page you are reading right now, which... Each box is smaller than its containing box. Where does this recursion stop?
49
6.3a Visual recursion and base cases
Before we understood human reproduction, it was thought that a woman was born with all of the complete humans inside of her that would ever be born
50
6.3a Visual recursion and base cases
Before we understood human reproduction, it was thought that a woman was born with all of the complete humans inside of her that would ever be born
51
6.3a Visual recursion and base cases
Before we understood human reproduction, it was thought that a woman was born with all of the complete humans inside of her that would ever be born. What could possibly go wrong?
52
6.3a Visual recursion and base cases
Question card What is wrong with the procreation story? Write and submit your answer 5 minutes for students to think and write this up
53
6.3a Visual recursion and base cases
Question card Try factorial without its base case public static int factorial(int n) { return n * factorial(n-1); } What do you see when you run this on factorial(2)? 5 more minutes for students to think and write this up
54
6.3a Visual recursion and base cases
What could possibly go wrong? Response: presumes an infinite amount of matter 5 minutes for response, including some 2 minutes of screenflow
55
6.3a Visual recursion and base cases
For factorial We see stack overflow We could make the stack bigger But it would still overflow Recursion without base cases leads to stack overflow This continues the response, and the screenflow is for this part End of BLT
56
For formulae, find substructure
6.3b Roundtable Roundtable 3b For formulae, find substructure sum(n) = n + (n-1) + (n-2) + … + 0 This is backwards from our earlier example Multiplication mpy(x,y) = x + x x (y times) Do some pictures, finding substructure Circles Drawing a line Sierpinski square snowflake from intro graph paper Why not ½ horizontally or vertically? 10 minutes, not much code here, just formulae and drawings. We want to refer to and point at the drawings and formula, perhaps on a shared screen?
57
Let's try to generate graph paper recursively
6.4 Example Oyster 4 Let's try to generate graph paper recursively
58
6.4 Example This is our goal but how do we see this recursively?
59
6.4 Example This is our goal but how do we see this recursively?
60
6.4 Example size (llx,lly)
61
6.4 Example size (llx, lly+size/2) (llx,lly)
62
6.4 Example size (llx+size, lly+size/2) (llx, lly+size/2) (llx,lly)
63
6.4 Example size (llx+size, lly+size/2) (llx, lly+size/2) (llx,lly)
64
6.4 Example size (llx+size/2, lly+size) (llx+size, lly+size/2)
(llx, lly+size/2) (llx,lly) (llx+size/2, lly)
65
6.4 Example size ul ul ur (ulx, uly) ll lr (llx,lly)
66
6.4 Example size ur ul ur (urx, ury) ll lr (llx,lly)
67
Example size ul ur ll ll lr (llx, lly)
68
Example size ul ur lr ll lr (lrx, lry) (llx,lly)
69
6.4 Example size size/2 ul ul ur (llx, lly+size/2) ll lr (llx,lly)
70
(llx+size/2,lly+size/2)
6.4 Example size size/2 ur ul ur (llx+size/2,lly+size/2) ll lr (llx,lly)
71
Example size ul ur size/2 ll ll lr (llx, lly)
72
Example size ul ur size/2 lr ll lr (llx+size/2, lly) (llx,lly)
6 minutes (llx+size/2, lly) (llx,lly) End of Oyster
73
6.5 Exercise Video intro Review slides and coordinates BLT 5 public
Video intro is about two minutes
74
6.5 Exercise Question card Think about Implement graph paper problem
Simplest substructure Base case This could take students 15 minutes to complete
75
6.5 Exercise Video response Show solution End of BLT
Video about 6 minutes, using screenflow End of BLT
76
6.6 There is no 6.6
77
How do we reason about the recursive behavior of methods?
6.7 Substitution model Oyster 7 How do we reason about the recursive behavior of methods? If they are functional meaning, they have no side effects Then we can substitute recursive calls mathematically wherever we see foo(x) we substitute the text of foo using x as its input Let's look at factorial again….
78
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) =
79
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 *
80
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 *
81
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 * 2 * fact(2-1)
82
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 * 2 * fact(2-1) = 3 * 2 * fact(1)
83
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 * 2 * fact(2-1) = 3 * 2 * fact(1) = 3 * 2 * 1 * fact(1-1)
84
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 * 2 * fact(2-1) = 3 * 2 * fact(1) = 3 * 2 * 1 * fact(1-1) = 3 * 2 * 1 * fact(0)
85
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 * 2 * fact(2-1) = 3 * 2 * fact(1) = 3 * 2 * 1 * fact(1-1) = 3 * 2 * 1 * fact(0)
86
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 * 2 * fact(2-1) = 3 * 2 * fact(1) = 3 * 2 * 1 * fact(1-1) = 3 * 2 * 1 * fact(0) = 3 * 2 * 1 * 1
87
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 * 2 * fact(2-1) = 3 * 2 * fact(1) = 3 * 2 * 1 * fact(1-1) = 3 * 2 * 1 * fact(0) = 3 * 2 * 1 * 1 = 3 * 2 * 1
88
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 * 2 * fact(2-1) = 3 * 2 * fact(1) = 3 * 2 * 1 * fact(1-1) = 3 * 2 * 1 * fact(0) = 3 * 2 * 1 * 1 = 3 * 2 * 1 = 3 * 2
89
Substitution model for recursive evaluation
public static int fact(n) { if (n==0) return 1; // I tend to put base case first else return n * fact(n-1); } fact(3) = 3 * fact(3-1) = 3 * fact(2) = 3 * 2 * fact(2-1) = 3 * 2 * fact(1) = 3 * 2 * 1 * fact(1-1) = 3 * 2 * 1 * fact(0) = 3 * 2 * 1 * 1 = 3 * 2 * 1 = 3 * 2 = 6
90
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0) = 3 – 2 – …. = 0 ? No, must keep computation in the boxes
91
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0) = 3 – 2 – …. = 0 ? No, must keep computation in the boxes Each box deserves a pair of parentheses
92
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1)
93
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0)
94
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0) = 3 – 2 – 1 – 0 mys(0) = 0
95
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0) = 3 – 2 – 1 – 0 = 3 – 2 – 1 - 0 mys(0) = 0 mys(1) = 1-0 = 1
96
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0) = 3 – 2 – 1 – 0 = 3 – 2 – 1 mys(0) = 0 mys(1) = 1-0 = 1
97
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0) = 3 – 2 – 1 – 0 = 3 – 2 – 1 = 3 – 2 - 1 mys(0) = 0 mys(1) = 1-0 = 1 mys(2) = 2-1 = 1
98
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0) = 3 – 2 – 1 – 0 = 3 – 2 – 1 = 3 – 1 mys(0) = 0 mys(1) = 1-0 = 1 mys(2) = 2-1 = 1
99
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0) = 3 – 2 – 1 – 0 = 3 – 2 – 1 = 3 – 1 = 3 - 1 mys(0) = 0 mys(1) = 1-0 = 1 mys(2) = 2-1 = 1
100
Substitution model for recursive evaluation
public static int mys(n) { if (n==0) return 0; // I tend to put base case first else return n – mys(n-1); } mys(3) = 3 – mys(2) = 3 – 2 – mys(1) = 3 – 2 – 1 – mys(0) = 3 – 2 – 1 – 0 = 3 – 2 – 1 = 3 – 1 = 2 mys(0) = 0 12 minutes mys(1) = 1-0 = 1 mys(2) = 2-1 = 1 End of Oyster
101
6.7b Practice doing substitution
BLT 7b public Let's practice substitution Always write = down the page fact(3) = 3 * fact(2) = etc 2 minute intro
102
6.7b Practice doing substitution
Question card For sum(n) sum(4) For add(x,y) now show substitution for add(10,3) 20 minutes for students to work on this
103
6.7b Practice doing substitution
Video response For sum(n) sum(4) For add(x,y) now show substitution for add(10,3) Response video 5 minutes, on a board or paper, no screenflow End of BLT
104
Use the debugger to trace recursive calls
6.7c Tracing recursion Roundtable Use the debugger to trace recursive calls Find the code in your repository 2 minute intro
105
Go over the following with each of the 3 students in roundtable:
6.7c Tracing recursion Go over the following with each of the 3 students in roundtable: For sum(n) sum(4) For add(x,y) now show substitution for add(10,3) For mys(n) mys(3) 15 total minutes of roundtable. The code would already be prepared, and the student would trace through it with me watching and commenting. End of Roundtable
106
Recursion is a powerful technique
6.8 Conclusion Monolog 8 Recursion is a powerful technique Nice results with relatively little coding Code often directly reflects the specified computation Ingredients of recursion Base case Recursive call Sometimes we have to find the substructure Best to find the next smallest subcase of the larger problem Substitution model helps us reason about recursion 2 minutes End of Monologue
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.