Introduction to Recursion
Lecture 4
Recursion
Recursion and Iteration
Sum of the first n natural Numbers
Recursion
Outline
Definition
Why do we need recursion
How recursion works internally
Implementation
Limitations and advantages
Conclusion
Questions
Recursion occurs when a thing is defined
in terms of itself or of its type.
Recursion
Recursion in our life
Matryoshka doll
Recursion
an = an-1 + 1, a1 = 1 an = n (polynomial)
an = 2 * an-1, a1 = 1 an = 2n-1 (exponential)
an = n * an-1, a1 = 1 an = n! (factorial)
Fn = Fn-1 + Fn-2 F0 = 0, F1 = 1 (Fibonacci number)
Recurrence Relations in Math
 Many natural functions are easily expressed as recurrences:
Recursion
Recursion in this course
 Recursion is one of the popular problem-solving
approaches in data structure
 Binary Trees
 Linked list algorithms
 DFS traversal of tree and graph
 Well-known algorithm design paradigms are
totally based on recursion:
 Divide and conquer
 Backtracking
 Top-down approach of dynamic programming
Spring 2014
In programming, is recursion a function
calls itself?
def sayHi():
print("hi")
sayHi()
def sayHi():
print("hi")
sayHi()
sayHi()
https://realpython.com/python-traceback/
Stack : a data structure which holds a
sequence of data and only allows you to
interact with the topmost item.
Adding to the top of the stack is called pushing.
Removing from the top of the stack is called popping.
In (push) Out(pop)
Top
FILO (First- In, Last - Out)
LIFO (Last - in, First - out)
Recursion
Stack in Python
Functions Description
push (value) Places given value on top of stack
pop( ) Removes top value from stack and returns it;
Throws EmptyStackException if stack is empty
peek( )/top( ) Returns top value from stack without removing it;
Throws EmptyStackException if stack is empty
size ( ) Returns number of elements in stack
empty ( ) Returns true If stack has no elements
Empty
Stack
1
2
1
3
2
1
2
1
3
Push(1) Push(2) Push(3) Pop
stack = [] # demonstrate stack implementation using list
stack.append(1)
stack.append(2)
stack.append(3)
print(stack.pop())
print(stack)
Output is :
3
[1, 2]
Stack frame
Stack frame
Module frame
Call stack : tracing all function calls,
handled behind the scene by Python
Local variables
A few other
information
Stack Frame
Call Stack
push: the execution enters a function
pop: the execution is done in a function
Stack Frame
def funcThree():
print('Three')
def funcTwo():
funcThree()
print('Two')
def funcOne():
funcTwo()
print('One')
funcOne()
Guess the output
Output is :
A) Three
Two
One
B) One
Two
Three
Module
funcOne( )
funcTwo( )
Call Stack
funcThree( )
Module
funcOne( )
funcTwo( )
Call Stack
..………….
Stack Overflow
funcThree( )
1000
The most-common cause of stack overflow is that the
recursion is excessively deep or is infinite.
In programming, recursion is a function
calls itself.
… until it doesn’t
Base case is used to stop
recursion
Recursive case
def fun1(a):
print("In fun1. Value received : ", a)
fun2(a)
def fun2(b):
print("In fun2. Value received : ", b)
fun3(b)
def fun3(c):
print("In fun3.")
d = 1
fun1(d)
print("End of main")
Output is :
A) In fun1. value received : 1
In fun2. value received : 1
In fun3.
End of main()
B) In fun3
In fun2. value received : 1
In fun1. value received : 1
End of main()
Module (d=1)
fun1 (a=1)
fun2 (b=1)
fun3 (c=1)
In fun1. Value received : 1
In fun2. Value received : 1
In fun3
End of main
Call Stack
Output is :
In method1. value received : 1
In method2. value received : 1
In method3.
End of main()
Call
Stack
Variables in stack frame
for module frame
In programming, recursion is a function
calls itself.
… until it doesn’t
Base case is used to stop
recursion
Recursive case
Recursion
Recursion Implementation
Continued
 Problem = smaller version of the same problem
(recursive call) + something known (base cases)
Big
problem
Smaller
problem
Yet
smaller
problem
Yet
smaller
problem
Recurse! Yet Yet smaller
problem
………
Base case
Recursion
Recursion implementation
1) Identify the recursive pattern
Each recursive call moves the solution
progressively closer to a base case.
2) Find the base case to stop the recursive calls
There are one or more base cases that are
directly solvable without the need for further
recursion.
Recursion
Recursion Implementation -
example
 Identity the pattern
 Define the base
case(s)
Recursive
reduction
……
factorial(n) = n * (n-1) *……* 4 * 3 * 2 * 1
= n * (n-1) *……* 4 * 3 * 2 * 1
= n * factorial(n-1)
(n-1) * factorial(n-2)
3* factorial(2)
2 * factorial(1)
2 * 1
factorial(n) = n * factorial(n-1) n > 1
1 n = 1
Factorial
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
n=int(input("Input a number to
compute the factorial : "))
print(factorial(n))
Base Case
Recursive
Case
• 5! = 5*4!
• 4! = 4*3!
• 3! = 3*2!
• 2! = 1*1!
• 1! = 1
A recursive function has at least one base case and one
recursive case.
Recursion
Tracing the factorial execution flow
def get_factorial_for_loop(n):
result = 1
for i in range(1, n+1):
result = result * i
return result
factorial - Iterative solution
In practice, recursion is not necessary:
any (computable) recursive function can
be rewritten using a loop and/or smart
data structure.
Recursion
Recursion vs. Iteration
 Recursion may be simpler, more intuitive
 Recursion may be efficient from programmer POV
 Recursion may not be efficient from computer POV
def get_factorial_for_loop(n):
result = 1
for i in range(1, n+1):
result = result * i
return result
def factorial(n):
if n == 1:
return 1
else:
return n *
factorial(n-1)
Recursion
Disadvantages of Recursion
module
factorial (3)
number = 3
factorial (2)
number = 2
factorial (1)
number = 1
factorial (4)
number = 4
factorial (5)
number = 5
def get_factorial_for_loop(n):
result = 1
for i in range(1, n+1):
result = result * i
return result
def factorial(n):
if n == 1:
return 1
else:
return n *
factorial(n-1)
1. Recursive functions can
“abuse” the call stack by
creating and destroying many
stack frames
2. Deep recursion risks stack
overflow
Recursion
Solving recurrence relation
using substitution
T(n) = 3 + T(n-1) if n > 1
2 if n = 1
def factorial(n):
if n == 1:
return 1
else:
return n *
factorial(n-1)
Recursion
Substitution – Another example
T(n) = T(n-1) + n if n > 1
c if n = 1
Recursion
Binary search
Recursion
Other approaches will be
covered by next lecture
 Spotting a pattern is sometimes difficult with the
substitution method
Avoiding Pitfalls
• Recursion can be extremely inefficient when
not done properly
• The same computations are performed over
and over multiple times
Recursion
Example- Fibonacci Sequence
F(0) = 0
F(1) = 1
F(n) = F(n-1) + F(n-2)
1. Can you write the python code to
implement this expression?
2. Can you write its recurrence relation and
draw its time complexity from it
Recursion
Analysis of Naïve Recursive Approach
Recursion
 Cn denote the number of calls performed in the execution
of Naïve recursive approach.
c0 = 1
c1 = 1
c2 = 1+c0+c1 = 1+1+1 = 3
c3 = 1+c1+c2 = 1+1+3 = 5
c4 = 1+c2+c3 = 1+3+5 = 9
c5 = 1+c3+c4 = 1+5+9 = 15
c6 = 1+c4+c5 = 1+9+15 = 25
c7 = 1+c5+c6 = 1+15+25 = 41
c8 = 1+c6+c7 = 1+25+41 = 67
T(n) = T(n-1) + T(n-2) + O(1) if n > 1
O(1) if n <= 1
Computing the nth Fibonacci number in
this way requires an exponential number of
calls to the function.
Recursion
Alternative solution:
memoization
 Save values so they can be reused (and not recomputed)
 Each recursive call checked to see if the value has been
computed before
 If yes: use it (avoid further recursion)
 If no: pay for the recursion, but store the answer
Recursion
memoization
Recursion
Bottom-up Fibonacci
Recursion
When to use/avoid recursion?
When to use it?
 When a problem has recursive feature
 When we are fine with extra overhead (both time
and space) that come with it
 When we need a quick working solution instead of
efficient one
 When traverse a tree/graph
When avoid it?
 If time and space complexity matters to the
problem
 Recursion uses more memory. If we use embedded
memory, for example an application that takes
more memory in the phone is not efficient
 Recursion can be slow
Recursion
Conclusion
 In programming, recursion is a function calls itself….. until it
doesn’t.
 To understand recursion, you must first understand stacks.
 Function calls push a stack frame onto the call stack, returning
pops them off.
 Recursion is hard to learn because the call stack is invisible.
 Stack overflows happen when you don’t set any base case or
make too many function calls without returning.
 A recursion function always needs at least one base case and one
recursive case.
 Anything you can do with recursion you can do with a loop.
 Using substitution method to find the time complexity for
recursive functions
 Avoiding repetitive computation using memoization and bottom-
up
Take the recursion quiz
on canvas
Recursive problems in Data Structures

lecture4-recursion.pptx

  • 1.
  • 2.
    Recursion Recursion and Iteration Sumof the first n natural Numbers
  • 3.
    Recursion Outline Definition Why do weneed recursion How recursion works internally Implementation Limitations and advantages Conclusion Questions
  • 4.
    Recursion occurs whena thing is defined in terms of itself or of its type.
  • 5.
    Recursion Recursion in ourlife Matryoshka doll
  • 6.
    Recursion an = an-1+ 1, a1 = 1 an = n (polynomial) an = 2 * an-1, a1 = 1 an = 2n-1 (exponential) an = n * an-1, a1 = 1 an = n! (factorial) Fn = Fn-1 + Fn-2 F0 = 0, F1 = 1 (Fibonacci number) Recurrence Relations in Math  Many natural functions are easily expressed as recurrences:
  • 7.
    Recursion Recursion in thiscourse  Recursion is one of the popular problem-solving approaches in data structure  Binary Trees  Linked list algorithms  DFS traversal of tree and graph  Well-known algorithm design paradigms are totally based on recursion:  Divide and conquer  Backtracking  Top-down approach of dynamic programming Spring 2014
  • 8.
    In programming, isrecursion a function calls itself? def sayHi(): print("hi") sayHi()
  • 9.
  • 11.
    Stack : adata structure which holds a sequence of data and only allows you to interact with the topmost item. Adding to the top of the stack is called pushing. Removing from the top of the stack is called popping. In (push) Out(pop) Top FILO (First- In, Last - Out) LIFO (Last - in, First - out)
  • 12.
    Recursion Stack in Python FunctionsDescription push (value) Places given value on top of stack pop( ) Removes top value from stack and returns it; Throws EmptyStackException if stack is empty peek( )/top( ) Returns top value from stack without removing it; Throws EmptyStackException if stack is empty size ( ) Returns number of elements in stack empty ( ) Returns true If stack has no elements
  • 13.
    Empty Stack 1 2 1 3 2 1 2 1 3 Push(1) Push(2) Push(3)Pop stack = [] # demonstrate stack implementation using list stack.append(1) stack.append(2) stack.append(3) print(stack.pop()) print(stack) Output is : 3 [1, 2]
  • 14.
    Stack frame Stack frame Moduleframe Call stack : tracing all function calls, handled behind the scene by Python Local variables A few other information Stack Frame Call Stack push: the execution enters a function pop: the execution is done in a function Stack Frame
  • 15.
    def funcThree(): print('Three') def funcTwo(): funcThree() print('Two') deffuncOne(): funcTwo() print('One') funcOne() Guess the output Output is : A) Three Two One B) One Two Three
  • 16.
  • 17.
    Module funcOne( ) funcTwo( ) CallStack ..…………. Stack Overflow funcThree( ) 1000 The most-common cause of stack overflow is that the recursion is excessively deep or is infinite.
  • 18.
    In programming, recursionis a function calls itself. … until it doesn’t Base case is used to stop recursion Recursive case
  • 19.
    def fun1(a): print("In fun1.Value received : ", a) fun2(a) def fun2(b): print("In fun2. Value received : ", b) fun3(b) def fun3(c): print("In fun3.") d = 1 fun1(d) print("End of main") Output is : A) In fun1. value received : 1 In fun2. value received : 1 In fun3. End of main() B) In fun3 In fun2. value received : 1 In fun1. value received : 1 End of main()
  • 20.
    Module (d=1) fun1 (a=1) fun2(b=1) fun3 (c=1) In fun1. Value received : 1 In fun2. Value received : 1 In fun3 End of main Call Stack Output is : In method1. value received : 1 In method2. value received : 1 In method3. End of main()
  • 21.
    Call Stack Variables in stackframe for module frame
  • 23.
    In programming, recursionis a function calls itself. … until it doesn’t Base case is used to stop recursion Recursive case
  • 24.
    Recursion Recursion Implementation Continued  Problem= smaller version of the same problem (recursive call) + something known (base cases) Big problem Smaller problem Yet smaller problem Yet smaller problem Recurse! Yet Yet smaller problem ……… Base case
  • 25.
    Recursion Recursion implementation 1) Identifythe recursive pattern Each recursive call moves the solution progressively closer to a base case. 2) Find the base case to stop the recursive calls There are one or more base cases that are directly solvable without the need for further recursion.
  • 26.
    Recursion Recursion Implementation - example Identity the pattern  Define the base case(s) Recursive reduction …… factorial(n) = n * (n-1) *……* 4 * 3 * 2 * 1 = n * (n-1) *……* 4 * 3 * 2 * 1 = n * factorial(n-1) (n-1) * factorial(n-2) 3* factorial(2) 2 * factorial(1) 2 * 1 factorial(n) = n * factorial(n-1) n > 1 1 n = 1
  • 27.
    Factorial def factorial(n): if n== 1: return 1 else: return n * factorial(n-1) n=int(input("Input a number to compute the factorial : ")) print(factorial(n)) Base Case Recursive Case • 5! = 5*4! • 4! = 4*3! • 3! = 3*2! • 2! = 1*1! • 1! = 1 A recursive function has at least one base case and one recursive case.
  • 28.
  • 29.
    def get_factorial_for_loop(n): result =1 for i in range(1, n+1): result = result * i return result factorial - Iterative solution In practice, recursion is not necessary: any (computable) recursive function can be rewritten using a loop and/or smart data structure.
  • 30.
    Recursion Recursion vs. Iteration Recursion may be simpler, more intuitive  Recursion may be efficient from programmer POV  Recursion may not be efficient from computer POV def get_factorial_for_loop(n): result = 1 for i in range(1, n+1): result = result * i return result def factorial(n): if n == 1: return 1 else: return n * factorial(n-1)
  • 32.
    Recursion Disadvantages of Recursion module factorial(3) number = 3 factorial (2) number = 2 factorial (1) number = 1 factorial (4) number = 4 factorial (5) number = 5 def get_factorial_for_loop(n): result = 1 for i in range(1, n+1): result = result * i return result def factorial(n): if n == 1: return 1 else: return n * factorial(n-1) 1. Recursive functions can “abuse” the call stack by creating and destroying many stack frames 2. Deep recursion risks stack overflow
  • 33.
    Recursion Solving recurrence relation usingsubstitution T(n) = 3 + T(n-1) if n > 1 2 if n = 1 def factorial(n): if n == 1: return 1 else: return n * factorial(n-1)
  • 34.
    Recursion Substitution – Anotherexample T(n) = T(n-1) + n if n > 1 c if n = 1
  • 35.
  • 36.
    Recursion Other approaches willbe covered by next lecture  Spotting a pattern is sometimes difficult with the substitution method
  • 37.
    Avoiding Pitfalls • Recursioncan be extremely inefficient when not done properly • The same computations are performed over and over multiple times
  • 38.
    Recursion Example- Fibonacci Sequence F(0)= 0 F(1) = 1 F(n) = F(n-1) + F(n-2) 1. Can you write the python code to implement this expression? 2. Can you write its recurrence relation and draw its time complexity from it
  • 39.
    Recursion Analysis of NaïveRecursive Approach
  • 40.
    Recursion  Cn denotethe number of calls performed in the execution of Naïve recursive approach. c0 = 1 c1 = 1 c2 = 1+c0+c1 = 1+1+1 = 3 c3 = 1+c1+c2 = 1+1+3 = 5 c4 = 1+c2+c3 = 1+3+5 = 9 c5 = 1+c3+c4 = 1+5+9 = 15 c6 = 1+c4+c5 = 1+9+15 = 25 c7 = 1+c5+c6 = 1+15+25 = 41 c8 = 1+c6+c7 = 1+25+41 = 67 T(n) = T(n-1) + T(n-2) + O(1) if n > 1 O(1) if n <= 1 Computing the nth Fibonacci number in this way requires an exponential number of calls to the function.
  • 41.
    Recursion Alternative solution: memoization  Savevalues so they can be reused (and not recomputed)  Each recursive call checked to see if the value has been computed before  If yes: use it (avoid further recursion)  If no: pay for the recursion, but store the answer
  • 42.
  • 43.
  • 44.
    Recursion When to use/avoidrecursion? When to use it?  When a problem has recursive feature  When we are fine with extra overhead (both time and space) that come with it  When we need a quick working solution instead of efficient one  When traverse a tree/graph When avoid it?  If time and space complexity matters to the problem  Recursion uses more memory. If we use embedded memory, for example an application that takes more memory in the phone is not efficient  Recursion can be slow
  • 45.
    Recursion Conclusion  In programming,recursion is a function calls itself….. until it doesn’t.  To understand recursion, you must first understand stacks.  Function calls push a stack frame onto the call stack, returning pops them off.  Recursion is hard to learn because the call stack is invisible.  Stack overflows happen when you don’t set any base case or make too many function calls without returning.  A recursion function always needs at least one base case and one recursive case.  Anything you can do with recursion you can do with a loop.  Using substitution method to find the time complexity for recursive functions  Avoiding repetitive computation using memoization and bottom- up
  • 46.
    Take the recursionquiz on canvas
  • 47.
    Recursive problems inData Structures

Editor's Notes

  • #2 Today, I’m going to talk about recursion, the title of my presentation is A beginner’s guide to recursion. This talk requires no background of Computer Science, students only need to know the basics of java programming. since all programming in this talk is in Java, the reason why I choose java is that the course 187 uses java as its programming language.
  • #3  every iterative approach can be turned into a "recursive" one, In any programming language, loops are used to execute repetitive statements such as a while loop and a for loop in python An entirely different way to achieve execution of a repetitive statements is through recursion. So recursion is a technique where a function or a method makes a call to itself.
  • #4 Definition: what is recursion Why do we need to learn recursion Stack and call stack: how recursion works internally
  • #5 Let’s start with the obvious/ˈäbvēəs/ question, what is recursion? If you go to the ultimate source of knowledge Wikipedia. You get something that says: After seeing this definition, can you explain what is the recursion to a 5 year old? I’m not kidding you,
  • #9 The definition for programming is a lot simpler: In programming, recursion is a function calls itself. Here is a very short example that captures this definition, a function calls sayHi, it only has two lines, the first line print out Hi, the second line it calls itself sayhi, Recursion is the idea that Taking a problem, reducing it to a smaller version of the same problem. Using the idea that touch really a bunch of real interesting problems. Recursion is get used to lots of places, so this idea is repeating the problem multiple times. The idea is I want to take a problem that I’m trying to solve, how could I reduce it to a simpler version of the same problem plus something that I know how to do. That simpler version, I am going to reduce again, and keep doing that until get down to a simple case that I can solve directly. That is how we think about designing a solution to a problem. A recursion is a function that call itself inside its body.
  • #10 As we know, the main method is the entry point of any java program. If you call this function in main method and run this program, actually, it doesn’t work. you will end up with this error. Python prints a traceback when an exception is raised in your code. The traceback output can be a bit overwhelming if you’re seeing it for the first time or you don’t know what it’s telling you. But the Python traceback has a wealth of information that can help you diagnose and fix the reason for the exception being raised in your code. Understanding what information a Python traceback provides is vital to becoming a better Python programmer. A traceback is a report containing the function calls made in your code at a specific point. Tracebacks are known by many names, including stack trace
  • #11 The Stack overflow is a pretty common error when you write a recursive function.. in order to precent this error How does a “stack overflow” occur and how do you prevent it? The call stack is a stack data structure that tracks function calls in a program. Before we really dive into recursion, I want to talk about stacks and the call stack, that is the stack in stack overflow, it’s difficult to understand recursion without knowing the stack and call stack.
  • #12 A stack is a simple data structure in computer science. Which is also called FIFL, since the first item you take it would be the last one you take out. The stack data structure only allows you to interact with the topmost item. A easy way to understand this data structure is these cups, you are only allowed to add a new cup or take out a cup on the top. With the stack data structure, you are only allowed to intereact with topmost items. There are two main operations we do with stack, adding some in is called pushing, taking something out is called popping. The stack of cups in this slide is a very good example of stack, since you are only allowed to add or remove a cup on the top. You can think of stack as this tack of cups, you are only allowed to interact with the topmost item, that is you can put in a new cup and take out a cup from the top. It is a data structure which holds a sequence of data and only allows you to interact with the topmost item. You can think of it as a stack of cups, a stack of books. You can only add or remove a cup or a book from the top, we call stack a FILO data structure, because the first cup or book you take it would be the last one you take out. a data structure which holds a sequence of data and only allows you to interact with the topmost item.
  • #13 The stack class in java is used to model and implement the stack data structure. It consist of these these methods. Among them, here are the two commonly used ones. That is push something onto the stack and pop something off the stack that is adding something to the top of the stack, that is the push method, removing something from the top of stack, the pop method. 5:47 Adding to the top of the stack is called pushing. Removing from the top of the stack is called popping.
  • #14 Here is a simple java program using stack class. First of all, I create a stack, which is empty. Then I push We want to print out the popped number and the remining numbers in the stack. This example exactly illustrates how the stack data structure works Again, the stack
  • #15 A stack frame represents a single function call. You can visualize functions that call one another as virtual frames stacking on top of one another. The stack data structure is actually used for this! When one function call returns its data to its caller, then its stack frame is removed from the stack. New stack frames are added and removed (along with their associated data) until the bottommost stack frame, sometimes called the module frame, gets the data it needs. The call stack is a stack  data structure that tracks function calls in a program. it is invisible to the programmer. In java, JVM manages the call stack automatically behind the scene. Understanding how the call stack works is essential to understand how recursion works. Call stack is made up of stack frames, one for each function call. It stores the local variables and a few other details associated with the function call. Here, I’m oversimplifying lots of stuff. If you are interested, you can refer to this link. The call stack is used to track function calls, actually the flow of execution in a program. The call stack is handle by java automatically behind the scenes. understanding how function store in program will understand how recursive function works  one stack frame represents one function call, within the frame, it stores the local variable and a few other details about the function.. I’m over simplifying lots of stuff here, you can refer to this link if you are interested in what’s inside a stack frame Let’s look at an example to see how the function calls tracked by the call stack. Take this program as an example, to simplify this program, we omit the codes before and after the function calls. Let’s see how the java handles the functions calls behind the scene.. JVM supports multithreaded execution environment. Each thread of execution has its private java virtual machine stack (JVM Stack) created at the same time of thread creation. This Java virtual machine stack stores frames. Frame holds data, partial results, method return values and performs dynamic linking. Each frame contains stack, known as Operand stack, which holds the operand values of JVM types. A depth of operand stack is determined at compile time and updated with operators. Each JVM thread has a private stack, created at the same time as the thread. A stack stores frames, also called “stack frames.” A stack frame is created every time a new method is called. When a method is invoked, a new stack frame is created to contain information about that method. Stack frames can have different sizes, depending on the method’s parameters, local variables, and algorithm. As the method is executed, the code can only access the values in the current stack frame, which you can visualize as being the top-most stack frame.
  • #16 First start with function calls that are not recursive. Then we will move to how recursive function works on the call stack Let’s take look at some code. It is a really standard java code, in which functions call functions. to simplify this program, I omit the codes before and after the function calls. Let’s see how the java handles the functions calls behind the scene.. Let’s see how java uses call stack to track the function calls I will use this code to explain how the how the call stack works step by step I think the really hard thing to understand recursion is , when you look at the code like this, you ask yourself, where is the call stack. You can not really point to a line of code and say “ here is the call stack , this variable contains the call stack. It is handle by java automatically behind the scenes.
  • #17 In this slide, I will show you how the call stack changes step by step in this program. I will use the function name to label its frame. When the execution enters a function, jvm will create and push a new frame onto the call stack. Within the frame, it stores the local variables and a few other information associate with the function. So first the main frame is pushed onto the stack. The a function is called within the main, at this time, JVM will save the return address, suspend the execution of main method and start to execute the a function. Then a frame is created and pushed onto the call stack. The b function is called within the a function, likewise, JVM will save the return address, suspend the execution of a function and started to execute the b function. So b frame is created and pushed onto the call stack. There are no function call in b function, the execution can be finished. Once it’s finished the b frame will pop off the call stack, the execution returns a function. Then it returns the main method. The whole program is done. When we do a function call, we are not sending the program execution to a one-way trip. To some other parts of our program. Java will remember the line that make that function call and can return back there afterwards When the execution enters a function, Java will create and push a new frame on to the call stack, within the frame, it stores the execution environment . Here we use the function name to refer the frame. So first the main frame is pushed onto the stack, within a function is called within the main function, java will remember where the call is made and suspend the current execution, then the execution enters the a function, java create and push a new frame called a onto the call stack and saves its environment in it. With the a ,it calls the b function, java will suspend the execution of b and start to execute b function. There is no function call in the b, it can be finished directly, once its finished , java will pop the frame off the call stack and return to execute the a function, Whenever the execution enters a method, the JVM creates and pushes a new frame onto the will push the method onto the call stack, so first the main method is pushed onto the call stack, within the main method, it calls the a method, at this moment, java will
  • #18 The interpreter limits the maximum number of times a function can call itself recursively, and when it reaches that limit, it raises a RecursionError exception, as you see above. As we can see, When we do a function call, we are not sending the program execution to a one-way trip. JVM will remember the line that make that function call, the execution can return back there afterwards Another thing I want to point out. As you can see each function call consumes some space in the call stack. Function calls can be deeply nested in a program. The size of the call stack is limited by a vm parameter. When your program use up all the space while it is still not finished. The stack Of course, you can increase the space by tuning this parameter. The function calls may be deeply nested in a program. Each function call consumes some space in the call stack. But the size of the call stack is fixed by a vm parameter, that is –xss. When all the space is running out and Yes, the limit is the size of the stack, which is controlled by a VM parameter, xss. when the space is running out while your program is still not finished. You will end up with the stack overflow error and your program will crashes You can change this parameter in order to get more space for your program. but I really wouldn’t recommend you do that, since the default value is big enough for most of the purposes. each function call will consume some space, there could be more function calls stored in the call stack, but the total size of the call stack is fixed and determined by a VM parameter. If your program run out of the memory while your program is still not finished. You will end up will the stack overflow error and your program will crash. Of course, method calls may be deeply nested. Is there a limit to method nesting depth? Yes. The limit is the size of the stack. This limit seems arbitrary. But it is big enough for most of the purposes. When the execution enters a function, Java will create and push a new frame on to the call stack, within the frame, it stores the execution environment . Here we use the function name to refer the frame. So first the main frame is pushed onto the stack, within a function is called within the main function, java will remember where the call is made and suspend the current execution, then the execution enters the a function, java create and push a new frame called a onto the call stack and saves its environment in it. With the a ,it calls the b function, java will suspend the execution of b and start to execute b function. There is no function call in the b, it can be finished directly, once its finished , java will pop the frame off the call stack and return to execute the a function, Whenever the execution enters a method, the JVM creates and pushes a new frame onto the will push the method onto the call stack, so first the main method is pushed onto the call stack, within the main method, it calls the a method, at this moment, java will
  • #19 The definition for programming is a lot simpler: In programming, recursion is a function calls itself. Here is a very short example that captures this definition, a function calls sayHi, it only has two lines, the first line print out Hi, the second line it calls itself sayhi, Recursion is the idea that Taking a problem, reducing it to a smaller version of the same problem. Using the idea that touch really a bunch of real interesting problems. Recursion is get used to lots of places, so this idea is repeating the problem multiple times. The idea is I want to take a problem that I’m trying to solve, how could I reduce it to a simpler version of the same problem plus something that I know how to do. That simpler version, I am going to reduce again, and keep doing that until get down to a simple case that I can solve directly. That is how we think about designing a solution to a problem. A recursion is a function that call itself inside its body.
  • #20 Hopefully you get a clear understanding of how t he call stack works by the previous step by step walkthrough. Here is an example to test your understanding. By explaining step by step with practical live code. I hope you can a better understand the call stack. Let’s look at another program. Here is an example to illustrate how the call stack works. a really standard normal java code. In which function call function. We have the main method call the a function, inside the a function, it calls the b function. At the start and end of the every function, we just have some print calls to show you when it starts and ends.
  • #21  Let’s do this again. First the execution enters the main method, the main frame is pushed onto the call stack, To understand what’s happening, we must look at how Java handles method calls. When a method is called, Java suspends what it is currently doing and pushes the environment on the stack to make place for the called method execution. When this method returns, Java pops the stack to restore the environment and resume program execution. If we call one method after the other, the stack will always hold at least one of these methods call environment. But methods are not only composed by calling them one after the other. Methods call methods. If method1 calls method2 as part of its implementation, Java again suspends method1 execution, pushes the current environment on the stack, and starts executing method2. When method2 returns, Java pops the last pushed environment from the stack and resume execution (of method1 in our case). When method1 completes, Java pops again from the stack and resume what it was doing before calling this method. Of course, method calls may be deeply nested. Is there a limit to method nesting depth? Yes. The limit is the size of the stack. In current situations, the limit is somewhere around a few thousands of levels, although it is possible to increase this limit by configuring the stack size. However, the same stack size is used for all threads, so increasig the stack size for a single computation will generally waste space. Default stack size varies between 320k and 1024k depending on the version of Java and the system used. For a 64 bits Java 8 program with minimal stack usage, the maximum number of nested method calls is about 7 000. Generally, we don’t need more, excepted in very specific cases. One such case is recursive method calls.
  • #22 If you debug this program in the elicpse, In the "debug perspective", show the view named "debug". this view shows the full call stack. Clicking on one stack will show variables of this stack element.
  • #23  Recursion would be a lot easier after you understandin all these concepts, let’s look at how The Stack overflow is a pretty common error when you write a recursive function.. in order to precent this error How does a “stack overflow” occur and how do you prevent it? The call stack is a stack data structure that tracks function calls in a program. Let’s look at how we write a recursive function to solve a real problem Before we really dive into recursion, I want to talk about stacks and the call stack, that is the stack in stack overflow, it’s difficult to understand recursion without knowing the stack and call stack.
  • #24 The definition for programming is a lot simpler: In programming, recursion is a function calls itself. Here is a very short example that captures this definition, a function calls sayHi, it only has two lines, the first line print out Hi, the second line it calls itself sayhi, Recursion is the idea that Taking a problem, reducing it to a smaller version of the same problem. Using the idea that touch really a bunch of real interesting problems. Recursion is get used to lots of places, so this idea is repeating the problem multiple times. The idea is I want to take a problem that I’m trying to solve, how could I reduce it to a simpler version of the same problem plus something that I know how to do. That simpler version, I am going to reduce again, and keep doing that until get down to a simple case that I can solve directly. That is how we think about designing a solution to a problem. A recursion is a function that call itself inside its body.
  • #25 Let’s look at how we use recursion to solve a problem. Given a problem, we need to check whether we can solve it by reducing the problem to a smaller version of the same problem, if we can, we keep doing reducing the problem until down to something we can solve directly. This two way trip looks like what we did in function calls. Excepted that the same function is called repeatly. In each call, it pass in differe Again, recursion is a function calls itself. The idea behind this definition is that some problems can be broken down into smaller versions of the same problem, which is also called recursive natural. There are a few examples that always uses recursion, let’s take one of them as an example to show you how can we program with recursion. The factorial. A really simple math concept, N factorial is n times (n-1) times (n-2) all the way to the 1 Here is the code to capture that. 5 factorial is 5 times 4 times 3 times 2 times 1. 2 factorial is 2 times 1 4 factorial is 4 times 3 times 2 times 1 You can get the idea how this works. Supposed we want to get the sum of integers from 1 to n, we introduce a method calls sumR(n) for this purpose. If we want to get the sum of all integers from 1 to 100. Taking one problem, that is the factorial, reduce the problem to a simpler version of the same problem, Keep doing this until down something that we can solve directly plus thing I know how would I do. How do I solve the (n-1) factorial, the same trick. Keep doing this until down something that I can solve directly: a base case. That is 1! = 1 When the base case is reached, the function returns its value to the function by whom it is called and memory is de-allocated and the process continues. You must always have some bases cases, which can be solved without recursion. Stop the recursion and prevent the infinite recursion When the base case is reached, the function returns its value to the function by whom it is called and memory is de-allocated and the process continues.
  • #27 The factorial (denoted or represented as n!) for a positive number or integer (which is denoted by n) is the product of all the positive numbers preceding or equivalent to n (the positive integer). The factorial function can be found in various areas of mathematics, including algebra, mathematical analysis, and combinatorics. Let’s look at how we use recursion to solve a problem. Given a problem, we need to check whether we can solve it by reducing the problem to a smaller version of the same problem, if we can, we keep doing reducing the problem until down to something we can solve directly. This two way trip looks like what we did in function calls. Excepted that the same function is called repeatly. In each call, it pass in differe Again, recursion is a function calls itself. The idea behind this definition is that some problems can be broken down into smaller versions of the same problem, which is also called recursive natural. There are a few examples that always uses recursion, let’s take one of them as an example to show you how can we program with recursion. The factorial. A really simple math concept, N factorial is n times (n-1) times (n-2) all the way to the 1 Here is the code to capture that. 5 factorial is 5 times 4 times 3 times 2 times 1. 2 factorial is 2 times 1 4 factorial is 4 times 3 times 2 times 1 You can get the idea how this works. Supposed we want to get the sum of integers from 1 to n, we introduce a method calls sumR(n) for this purpose. If we want to get the sum of all integers from 1 to 100. Taking one problem, that is the factorial, reduce the problem to a simpler version of the same problem, Keep doing this until down something that we can solve directly plus thing I know how would I do. How do I solve the (n-1) factorial, the same trick. Keep doing this until down something that I can solve directly: a base case. That is 1! = 1 When the base case is reached, the function returns its value to the function by whom it is called and memory is de-allocated and the process continues. You must always have some bases cases, which can be solved without recursion. Stop the recursion and prevent the infinite recursion When the base case is reached, the function returns its value to the function by whom it is called and memory is de-allocated and the process continues.
  • #28 So we need to change this function, here is the hint, 1 factorial equals 1. if we check whether the number is 1 we can return 1 directly. This is called the base cases. The set of circumstances that the recursion function will stop recursion. The other side of that is the recursion case, it is the code that does the recursion. In every single function that you write that’s recursive. You have at least one base case , otherwise it will keep recursing forever and cause stack overflow. We need to have at least one recursive case, because otherwise it is not a recursive function if it doesn’t call itself. So whenever you are writing code for recursion, it is a great starting point to think what is my base case, and what’s recursive case. Make sure your recursive case eventually hits one of the base cases. Some people may still confused. Where does the 5 times 4 times 3 times 2 times 1 happen? How does this serial of multiplication happen? . , and one recursive case. Here is the code to catch the idea. Is the number equals 1, that is just 1. this is the base case. Otherwise, I’m goanna solve the problem using a smaller version multiple the number. Recursive definition is reducing the problem to a simpler version of the same problem. Base case: for what values can we solve without another recursive call “How does the 5 × 4 × 3 × 2 × 1 happen?”
  • #30 Let’s solve the problem in a different way. Using iterative solution. Set up a iterative variable and a local variable that used to accumulate things. After each iteration, j increased by 1 until it goes up to n
  • #31 Let’s show you side by side the two different version of factorial. Which one do you like more? You can’t say neither, you have to pick one. Show your hands. How many of you like this one? How many prefer this one? Yeah. That’s my view. I am biased. I really like the recursive one. Because it is more intuitive to understand. It is in fact very straightforward. From a programmer’s perspective, it’s more efficiently write. Because I don’t need to think about iterative variables. Depending on the machine, it may not efficiently call it. Because for a recursive version, it needs to set up that set of frames. But given the speed of the current computer, who cares as long as you finish the computation. any problem that can be solved recursively can also be solved through the use of iteration.
  • #33 Let’s show you side by side the two different version of factorial. Which one do you like more? You can’t say neither, you have to pick one. Show your hands. How many of you like this one? How many prefer this one? Yeah. That’s my view. I am biased. I really like the recursive one. Because it is more intuitive to understand. It is in fact very straightforward. From a programmer’s perspective, it’s more efficiently write. Because I don’t need to think about iterative variables. Depending on the machine, it may not efficiently call it. Because for a recursive version, it needs to set up that set of frames. But given the speed of the current computer, who cares as long as you finish the computation. any problem that can be solved recursively can also be solved through the use of iteration.
  • #34 Recurrence Relations
  • #39 Just in case, you are not familiar with it. I put the expression on this slide. Each Fibonacci number is by adding up its two previous numbers. Don’t worry, let’s draw the recursion tree
  • #40 Don’t worry, let’s draw the recursion tree. Duplicate work. The tree shows that it does a lot of repetitive computations. It is quite slow. Actually using this naïve way to compute Fibonacci, the time complexity is about O(2 to the power of n), see textbook for explanation
  • #43 Time complexity O(n)
  • #48 Recursion is a a powerful and wonderful tool for solving lots of computation problems, especially for these two structure, tree structure and file directory structure. With recursion, the problem is a lot easier to write than using while and for loops. Advantage Recursion reduces the length of the code. Code becomes easier to read. Primarily used when dealing with tree data structures. When the problem has a tree-like structure. When the problem requires backtracking.