Basic Recursion¶
Recursion can be tricky to understand, especially when it comes to the order of operations. Here, we'll try to understand what happens when you "do" something before the recursive call (preorder position) or after the recursive call (postorder position).
Debug this in your IDE and see what is happening on the stack and how function calls are stacked and unwound.
Understanding Recursive Positions¶
- Preorder Position: Operations performed before the recursive call
- Postorder Position: Operations performed after the recursive call
- Base Case: Condition to stop recursion
Implementation Approaches¶
Print i to 5 forwards and backwards
Input is the starting point .Use preorder position to print in ascending order and postorder position to print in reverse order. Base Case is when i exceeds 5.
"""
Print Numbers from i to 5.
"""
def print_nums(i) :
if i > 5 :
return
#preorder position
print(i)
#recursive call
print_nums(i+1)
"""
Print Numbers from i to 5 in reverse order
"""
def print_nums_backwards(i) :
if i > 5 :
return
#recursive call
print_nums_backwards(i+1)
#postorder position
print(i)
print_nums(1)
print_nums_backwards(1)
Print numbers forward and backward in the range 1 to n.
n is the input parameter to the function. Base case is when n becomes less than 1 i.e. equal to zero. Here, we have to print in postorder position to get the output in ascending order. We use preorder position to print in descending order. This is becuase we are taking the upper bound as input. Whereas, in the previous example, we took the lower bound as input.
"""
Print Numbers from 1 to n .
"""
def print_nums_1_to_n(n) :
if n == 0 :
return
print_nums_1_to_n(n-1)
print(n)
#print 1 to n
print_nums_1_to_n(5)
"""
Print Numbers from n to 1 .
"""
def print_nums_n_to_1(n) :
#base cases
if n == 0 :
return
print(n)
print_nums_n_to_1(n-1)
print_nums_n_to_1(5)
Approach 3: Print Both Ways
Uses both preorder and postorder positions to print numbers in both orders.
"""
Print Numbers n to 1 and then 1 to n
"""
def print_nums(n) :
if n == 0 :
print("Base Case Hit.")
return
#preorder position
print(f"Preorder : {n}")
#recursive call
print_nums(n-1)
#postorder position
print(f"Postorder : {n}")
print_nums(5)
Comparison of Approaches¶
Position | When Operation Happens | Stack State | Output Order |
---|---|---|---|
Preorder | Before recursive call | During stack building | Same as Inout Order |
Postorder | After recursive call | During stack unwinding | Reverse of Input Order |
Both | Before and after | Both phases | Both orders |
Key Takeaways
- Operation Placement: The position of operations relative to the recursive call determines the order of execution
- Stack Behavior:
- Stack builds up: Follows input order (n → n-1 → n-2 → ... → 1)
- Stack unwinds: Reverse of input order (1 → 2 → ... → n-1 → n)
- Memory Usage: All approaches use O(n) stack space
- Choose Based On:
- Same as input order → Use preorder position
- Reverse of input order → Use postorder position
- Both orders → Use both positions