ICS 2105 - Lecture Notes - Topic 5
ICS 2105 - Lecture Notes - Topic 5
Topic: Recursion
TOPIC: RECURSION
1. Topic Purpose:
The topic "Recursion" in Data Structures and Algorithms is aimed at helping undergraduate
Information Technology students understand how certain problems can be solved more
efficiently using recursive techniques. Recursion provides a different way of thinking about
problem-solving by allowing a function to call itself in order to break down a complex problem
into smaller, more manageable parts. This concept is foundational for understanding many
advanced topics such as backtracking, divide and conquer algorithms, and dynamic
programming. By the end of this topic, students should be able to confidently apply recursion to
solve programming problems and understand how it works behind the scenes in memory.
2. Learning Objectives:
3. Detailed Notes:
Recursion is a programming technique where a function calls itself to solve smaller instances of
the same problem. In simple terms, recursion allows a problem to be defined in terms of itself. It
breaks down a problem into smaller sub-problems and then solves each of those recursively. This
approach is particularly useful when the problem can be naturally divided into similar sub-
problems.
Imagine you are looking at a mirror that reflects another mirror. What you see is a repeated
image going into the distance. Recursion works similarly, where a function keeps calling itself
until a certain condition is met.
1. Base Case: This is the condition that stops the recursion. Without a base case, the
function would call itself forever, leading to a stack overflow error.
Dr. Lango 1
ICS 2105 – DATA STRUCTURES AND ALGORITHMS
2. Recursive Case: This is the part of the function where the function calls itself.
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)
• factorial(2) = 2 * 1 = 2
• factorial(3) = 3 * 2 = 6
When a function is called, the computer stores information about that call in a special memory
structure called the call stack. Every recursive call adds a new frame to the call stack. When a
base case is reached, the calls start resolving from the most recent one back to the first.
This is why recursion can be memory-intensive if the depth of recursion is large. If there are too
many recursive calls without reaching the base case, the stack may overflow.
1. Fibonacci Series:
Dr. Lango 2
ICS 2105 – DATA STRUCTURES AND ALGORITHMS
The Fibonacci sequence is a series of numbers where each number is the sum of the two
preceding ones. It starts like this: 0, 1, 1, 2, 3, 5, 8, ...
Recursive implementation:
def fibonacci(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
def sum_n(n):
if n == 1:
return 1
else:
return n + sum_n(n - 1)
def reverse_string(s):
if len(s) == 0:
return s
else:
return reverse_string(s[1:]) + s[0]
Both recursion and iteration can be used to solve the same problems, but they differ in approach.
• Recursion is cleaner and more intuitive for problems that have a natural recursive
structure (like tree traversal).
• Iteration is generally more efficient in terms of memory.
def factorial_iterative(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
Dr. Lango 3
ICS 2105 – DATA STRUCTURES AND ALGORITHMS
• The problem can be broken down into smaller sub-problems of the same type.
• The number of sub-problems is not large enough to cause memory issues.
• The recursive approach makes the code cleaner and easier to understand.
• Tree traversal
• Graph traversal
• Solving puzzles like Tower of Hanoi
• Backtracking problems (e.g., Sudoku)
• Divide and conquer algorithms (e.g., Merge Sort, Quick Sort)
Tail recursion is a special form of recursion where the recursive call is the last operation in the
function.
Example:
Some programming languages optimize tail recursion to prevent stack overflow. However,
Python does not perform tail recursion optimization.
• Can lead to performance issues due to overhead from multiple function calls.
• Uses more memory because each function call is stored on the call stack.
• Risk of stack overflow if the base case is not properly defined or recursion is too deep.
Sometimes, you may need to convert a recursive function to an iterative one for better
performance. This involves using loops and stacks to mimic the call stack.
Dr. Lango 4
ICS 2105 – DATA STRUCTURES AND ALGORITHMS
3.12 Summary
Recursion is a powerful tool in programming that helps solve problems by breaking them down
into smaller parts. It involves a function calling itself and relies on a base case to stop the
recursion. While recursion is elegant and closely matches mathematical definitions, it must be
used carefully to avoid memory issues. Through practice with standard problems like factorial,
Fibonacci, and tree traversals, students can become proficient in applying recursion effectively in
their programming tasks.
Understanding recursion lays the foundation for tackling more complex algorithmic problems
and mastering advanced topics in data structures and algorithms.
Dr. Lango 5