Download presentation
Presentation is loading. Please wait.
1
University of Washington Computer Programming I
Recursion Su00 tvi: Reverted to earlier version without mergesort code. Added explicit discussion of base vs recursive case, and making progress towards termination. Added Richard Anderson’s favorite “why does this terminate/we don’t know” example. Added explicit parallel between recursive mathematical definitions and recursive functions. Got rid of the inane recursive “insist on y or n” example. It’d be nice to have a non-numeric example, but it’s gotta be one that’s not contrived. Maybe best left to divide-and-conquer algorithms in CSE 143 © 2000 UW CSE
2
Overview Review Function calls in C Concepts
Recursive definitions and functions Base and recursive cases
3
Factorial Function Factorial is an example of a mathematical function that is defined recursively, i.e., it is partly defined in terms of itself. Su00 tvi: Added. This seems to be a nice place to start, rather than just saying “a recursive function is one that calls itself” Students have seen definition by cases in their high-school math. I always bring this up to provide a bridge to something they already know. I think I may have found a program with a less intuitive interface than PowerPoint: the MS Equation Editor! Ugh!
4
Factorial Revisited We’ve already seen an implementation of factorial using a loop int factorial ( int n ) { int product, i ; product = 1 ; for ( i = n ; i > 1 ; i = i - 1 ) { product = product * i ; } return product ; Su00 tvi: Probably useful to have a reminder that we’ve been here before 1! is 1 2! is 1 * 2 3! is 1 * 2 * 3 4! Is 1 * 2 * 3 * 4 5! Is 1 * 2 * 3 * 4 * 5 . .
5
Factorial, Recursively
But we can use the recursive definition directly to get a different version /* Compute n factorial – the product of the first n integers, 1 * 2 * 3 * * n */ int factorial(int n){ int result; if (n <= 1) result = 1; else result = n * factorial(n - 1); return result; } Su00 tvi: could return result directly, but it’s helpful to have a local variable for the (eventual) full trace. Style point: for a value-returning function, simply writing a description of that value in the heading coment is often sufficient - but there’s got to be a heading comment.
6
24 Trace factorial(4) = 4* factorial(3) = 4* 3 * factorial(2) =
int factorial(int n){ int result; if (n <= 1) result = 1; else result = n * factorial(n - 1); return result; } 4* 3 * 2 * 1 = Su00 tvi: left this in - this is an “evaluation by substitution” trace. It gives an example of recursive evaluation without getting into stack frames or activation records. I think it’s useful to get across the notion of recursive evaluation in a nice, simple setting before we start to mess things up with implementation details. Animation added - click away to get the computation to unfold. Also tried to get a sense of the return values, which was not on the previous version of this slide. When I do this in class, I talk through the program step-by-step (“Is n<=1? No it’s not, so we need to calculate 3*factorial(3-1) or 3*factorial(2)…..” The function may be too small to be legible on TV, but they should have the handouts or previous slide, and putting the tiny version in adds some continuity. 4* 3 * 2 = 24 4* 6 =
7
What is Recursion? Definition: A function is recursive if it calls
itself int foo(int x) { … y = foo(…); } Su00 tvi: This used to lead off the lecture with a couple of rhetorical questions. I think it works better here. How can this possibly work???
8
Function Calls Answer: there’s nothing new here!
Remember the steps for executing a function call in C: Allocate space for called function’s parameters and local variables Initialize parameters Begin function execution Recursive function calls work exactly the same way New set of parameters and local variables for each (recursive) call Su00 tvi: Replaced previous review with repeat of the rules we used earlier to make it clear that nothing new is going on here. The only change is that we’re going to be executing the same code on a different set of variables.
9
Trace k main 24 24 n factorial result 24 4 6 n factorial result 6 3 2
int factorial(int n){ int result; if (n <= 1) result = 1; else result = n * factorial(n - 1); return result; } int main(void) { … k = factorial(4); ... k main 24 24 n factorial result 24 4 6 n factorial result 6 3 2 Su00 tvi: Animation added and things reformatted to fit on slide. The animation is pretty fine-grained. Each function call has allocation and parameter initialization separately. There is a separate display of the function result value before it is multiplied into the previous value of n and stored in result. n factorial result 2 2 n factorial result 1 1 1
10
Recursive & Base Cases A recursive definition has two parts
One or more recursive cases where the function calls itself One or more base cases that return a result without a recursive call There must be at least one base case Every recursive case must make progress towards a base case Forgetting one of these rules is a frequent cause of errors with recursion Su00 tvi: new. Might want to amplify that the recursive call could be indirect - call a different function that eventually calls the original one - but I don’t want to clutter the slide further.
11
Recursive & Base Cases Base case Recursive case int factorial(int n){
int result; if (n <= 1) result = 1; else result = n * factorial(n - 1); return result; } Base case Recursive case Su00 tvi: new
12
Does This Run Forever? Check: Includes a base case? Yes
Recursive calls make progress? Hmmm… int f (int x) { if (x == 1) return 1; else if (x % 2 == 0) return 1 + f(x/2); else return 1 + f(3*x + 1); } Answer: Not known!!! In tests, it always gets to the base case eventually, but nobody has been able to prove that this must be so! Su00 tvi: new. Animation: answer to second question is hidden at first. Open question for the mathematically minded.
13
3N + 1 function f(5) = 1 + f(16) = 2 + f(8) = 3 + f(4) = 4 + f(2)
= 6 f(7) = 1 + f(22) = 2 + f(11) = 3 + f(34) = 4 + f(17) = 5 + f(52) = 6 + f(26) = 7 + f(13) = 8 + f(40) = 9 + f(20) = 10 + f(10) = 11 + f(5) = 12 + f(16) = 13 + f(8) = 14 + f(4) = 15 + f(2) = 16 + f(1) = 17
14
When to use Recursion? Problem has one or more simple cases
These have a straightforward nonrecursive solution, and: Other cases can be redefined in terms of problems that are closer to simple cases By repeating this redefinition process one gets to one of the simple cases
15
Summary Introduced recursion Functions that call themselves
Base and recursive cases Simple examples Factorial 3N + 1 function An important concept with many uses
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.