## Introduction to Recursion

## Understanding the Recursive Process

` ````
```
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)

` ````
```
def fibonacci_recursive(n):
if n <= 1:
return n
else:
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)

## Drawbacks

### 1. The Stack Overhead

Recursion becomes problematic when there is no proper termination condition, and the recursive calls keep piling up without ever reaching a base case. This can lead to stack overflow errors, where the stack memory gets exhausted, and the program can no longer handle additional function calls.

Main Idea

` ````
```
print(factorial(10000))

To prevent this error, you can either increase the maximum recursion depth limit in Python settings or modify the code to use an iterative approach instead of recursion. By using an iterative solution, you avoid the risk of a stack overflow error caused by excessive recursive calls.

-- Tip

### 2. Memory Consumption

To avoid excessive memory consumption, it's important to consider alternative approaches or optimize the recursive functions such as memoization, which stores previously calculated results to avoid redundant computations.

-- Tip

### 3. Time Complexity

**Let’s Consider the above fibonacci_recursive function!**

It's important to carefully assess the problem and consider alternative approaches to optimize performance when dealing with recursive solutions. By employing techniques like memoization or dynamic programming, we can significantly improve the efficiency and speed of recursive algorithms.

-- Tip

### 4. debugging challenges

**Let me explain it in a simpler way.**

` ````
```
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n + 1) # Intentional bug: incorrect recursive call
# Testing the factorial function
num = 5
result = factorial(num)
print(f"The factorial of {num} is: {result}")

Debugging tools and techniques, such as stepping through the code, inspecting variables, visualizing the call stack, breaking down problems into smaller subproblems, and adding logging or print statements, help understand and overcome challenges in recursive code.

-- Tip

### 5. limited applicability

**Imagine you’re in a library, and you want to find a particular book on a specific topic. All the books are shuffled and not organised in order.**

**Why?**

## Better approach

` ````
```
def factorial_recursive(n):
if n == 0:
return 1
else:
return n * factorial_recursive(n-1)

` ````
```
def factorial_iterative(n):
result = 1
for i in range(1, n+1):
result *= i
return result

**Recursive approach**:

` ````
```
def fibonacci_recursive(n):
if n <= 1:
return n
else:
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)

**Memoized version of the Fibonacci function**:

` ````
```
def fibonacci_memoized(n, memo={}):
if n <= 1:
return n
elif n not in memo:
memo[n] = fibonacci_memoized(n-1, memo) + fibonacci_memoized(n-2, memo)
return memo[n]

**Iterative approach**:

` ````
```
def fibonacci_iterative(n):
if n <= 1:
return n
else:
fib_list = [0, 1]
for i in range(2, n + 1):
fib_list.append(fib_list[i-1] + fib_list[i-2])
return fib_list[n]

## Conclusion

## Go further

- Programiz:
**Python Recursion** - The modern JavaScript Tutorial :
**Recursion and stack** - IBM Developer:
**Mastering recursive programming**