a factorial Base case #1: if n is negative, return -1, because factorial is undefined Base case #2: if n is 0 or 1, return 1 Recursive case: return n * (method call for n-1)
base or recursive case • We must have at least one base case to stop the recursion • The recursive case must make the problem smaller in some way, or we will get infinite recursion
to 1 and multiplying the numbers • O(n), because we must loop though each number • Recursive factorial algorithm of having a base case (if n is 1) and recursive case to multiply numbers • O(n), because have a method call for each number
4! • The box trace shows the runtime stack for the recursive() method • You should open jGRASP and make the line numbers visible, so you can trace though the program with me
lines #84 and #88 are false, so program control goes to the else statement on line #91 • This is the recursive case • Runtime stack return address=B number=4
multiplies number by the method call with argument (number-1), which pushes the return address C and argument 3 • Runtime stack return address=C number=3 Box Trace return address=B number=4 return value=4*m(3)
line #82 • The two if statements are false, so the program goes to the recursive case again • Runtime stack return address=C number=3 return address=B number=4 return value=4*m(3)
to the beginning of the method • The two if statements are false, so next is recursive case • Runtime stack return address=B number=4 return value=4*m(3) return address=C number=3 return value=3*m(2) return address=C number=2
the beginning of the method, line #82 • On line #88, the if statement is true, so the base case returns 1 return address=C number=1 return value=1 return address=B number=4 return value=4*m(3) return address=C number=3 return value=3*m(2) return address=C number=2 Return value=2*m(1)
pops off the bottom most ARI on the stack, and returns the return value 1 to return address C on line #94 return address=B number=4 return value=4*m(3) return address=C number=3 return value=3*m(2) return address=C number=2 return value=2*1=2 • Runtime stack Box Trace
return statement pops off the bottom most ARI on the stack, and returns the return value 2 to return address C on line #94 return address=B number=4 return value=4*m(3) return address=C number=3 return value=3*2=6 • Runtime stack
return statement pops off the bottom most ARI on the stack, and returns the return value 6 to return address C on line #94 return address=B number=4 return value=4*6=24 • Runtime stack
return statement pops off the bottom most ARI on the stack, and returns the return value 24 to return address B on line #41 • Runtime stack • The main() method has an ARI as well args[0]="4" number=4 result=24 result2=24
code with a red dot breakpoint, press ladybug button, and press the “Step in for selected thread” button (top left blue arrow curving down to the right) • Also check out the call stack window to see the ARI for each method
-1 (for error condition) 2. If y is 0, return 1 (special condition) 3. Initialize local variable product = 1 4. Loop from 1 to y 5. Within loop, multiply x by product, and store result in product 6. Return product
-1: O(1) 2. If y is 0, return 1: O(1) 3. Initialize local variable product = 1: O(1) 4. Loop from 1 to y: O(n) 5. Within loop, multiply x by product, and store result in product: O(1) 6. Return product: O(1)
make the problem smaller • This usually involves subtracting a number or letter from a variable • The return statement has the method call for the same method, but the argument in the method call should be a smaller value
is negative, return -1 (error) 2. Base case #2: if y equals 0, return 1 (mathematical definition) 3. Recursive case: return x * (method call with argument y-1)
so straightforward • We need to think about how many steps must be taken to reach base case from the recursive case for n • Equivalent to the number of ARIs (boxes with local environment data) pushed to the runtime stack
of argument x does not change, but the value of argument y decreases by 1 for each recursion • So we have y + 1 steps, as the base case is true when y is 0 • O(n+1) = O(n)
1, 2, 3, 5, 8, 13, 21, 34, 55, ... • At least 2000 years ago, this series of numbers was known in India • Named after Leonardo Fibonacci who used the series to predict idealized breeding rates of rabbits in 1202
program Fibonacci.java Compare the two methods by number of method calls which are displayed as program output The recursive method has many more method calls than the iterative method!
for each recursion • O(2n), because we have to double the number of method calls each time n increases by 1 (one) • This is an example of exponential Big- O, which has a very long runtime
and short Easy to read, understand and maintain the code • Disadvantages to recursion Because of method call overhead, an equivalent iterative solution is faster to execute on today’s computers
1.Do the assignment corresponding to this lecture 2.Email me any questions you may have about the material 3.Turn in the assignment before the next lecture 4.Take a break by going on a nice hike!