FEBRUARY 22, 2025
UNDERSTANDING
RECURSIONS IN C LANGUAGE
VAMSI KRISHNA VAKA
Recursion
What is Recursion?
Recursion is a technique in programming where a function calls itself directly or indirectly to solve a
problem. It is widely used for problems that can be broken down into smaller subproblems with a
base case to stop the recursion.
Key Concepts of Recursion
1. Base Case: The stopping condition to prevent infinite recursion.
2. Recursive Case: The part of the function where it calls itself with a smaller or simpler input.
3. Stack Memory Usage: Each recursive call is stored in the call stack, and when the base case
is met, the stack starts unwinding.
4. Mathematical Induction Approach: Recursion works on the principle of breaking a large
problem into smaller problems and solving each recursively.
Syntax of a Recursive Function
return_type function_name(parameters)
if (base_condition)
return base_value; // Base condition
else
return recursive_function(modified_parameter); // Recursive condition
Example 1: Factorial Calculation
Factorial using Recursion in C
#include <stdio.h>
int factorial(int n)
if (n == 0) // Base case
return 1;
else
return n * factorial(n - 1); // Recursive call
}
int main()
int num = 5;
printf("Factorial of %d is %d\n", num, factorial(num));
return 0;
Execution Breakdown for factorial(5)
Call Stack Execution
factorial(5) = 5 * factorial(4)
factorial(4) = 4 * factorial(3)
factorial(3) = 3 * factorial(2)
factorial(2) = 2 * factorial(1)
factorial(1) = 1 * factorial(0)
factorial(0) = Returns 1 (Base Case)
Now the function starts returning:
• 1*1=1
• 2*1=2
• 3*2=6
• 4 * 6 = 24
• 5 * 24 = 120
Final Output: Factorial of 5 is 120
Example 2: Sum of Digits of a Number
sum(123)=1+2+3=6
#include <stdio.h>
int sumOfDigits(int n)
if (n == 0) // Base case
return 0;
return (n % 10) + sumOfDigits(n / 10); // Recursive call
int main()
int num = 1234;
printf("Sum of digits: %d\n", sumOfDigits(num));
return 0;
Execution Breakdown
Call Stack Execution
sumOfDigits(1234) = 4 + sumOfDigits(123)
sumOfDigits(123) = 3 + sumOfDigits(12)
sumOfDigits(12) = 2 + sumOfDigits(1)
sumOfDigits(1) = 1 + sumOfDigits(0)
sumOfDigits(0) = Returns 0 (Base Case)
Now it returns:
• 1+0=1
• 2+1=3
• 3+3=6
• 4 + 6 = 10
Final Output: Sum of digits: 10
Types of Recursion
Recursion can be classified into several types:
1. Direct Recursion
• A function calls itself directly.
void functionA()
if (condition)
return;
functionA();
• Example: Factorial function.
2. Indirect Recursion
• A function calls another function, which calls the first function again.
void functionA();
void functionB();
void functionA()
if (condition)
return;
functionB();
void functionB()
if (condition)
return;
functionA();
Example:
#include <stdio.h>
void even(int n);
void odd(int n);
void even(int n)
if (n == 0)
printf("Even\n");
else
odd(n - 1);
}
void odd(int n)
if (n == 0)
printf("Odd\n");
else
even(n - 1);
int main()
even(10); // Output: Even
odd(7); // Output: Odd
return 0;
3. Tail Recursion
• The recursive call is the last operation before returning.
• Optimized by the compiler (Tail Call Optimization).
void tailRecursion(int n)
if (n == 0)
return;
printf("%d ", n);
tailRecursion(n - 1); // Tail call
• Example: Printing numbers from n to 1
#include <stdio.h>
void printNumbers(int n)
if (n == 0)
return;
printf("%d ", n);
printNumbers(n - 1);
}
int main()
printNumbers(5);
return 0;
Output: 5 4 3 2 1
4. Non-Tail Recursion
• The recursive call is not the last operation.
• Uses more stack memory compared to tail recursion.
int nonTailRecursion(int n)
if (n == 0) return 0;
return n + nonTailRecursion(n - 1); // Recursive call is not last
Example: Sum of first n natural numbers
#include <stdio.h>
int sum(int n)
if (n == 0) return 0;
return n + sum(n - 1);
int main()
printf("Sum: %d\n", sum(5));
return 0;
Output: Sum: 15 (5+4+3+2+1)
Pros and Cons of Recursion
Advantages
• Simplifies complex problems like tree traversal, factorial, Fibonacci.
• Reduces the need for loops, making code cleaner.
Disadvantages
• High memory usage due to function call stack.
• Performance overhead due to repeated function calls.
• Risk of stack overflow if recursion depth is too high.
How to Improve Problem-Solving Using Recursion?
To improve problem-solving using recursion, follow these 5 key steps:
Step 1: Identify if the problem can be divided into smaller parts
Step 2: Define the base case (when recursion should stop)
Step 3: Write the recursive case (how the function calls itself)
Problem Statement: Sum of Digits of a Number Using Recursion
Given an integer n, write a recursive function to find the sum of its digits.
Step-by-Step Solution
Step 1: Identify if the problem can be divided into smaller parts
• The sum of digits can be broken down into the last digit and the sum of the remaining digits.
• Example: 123 → (3) + sum(12)
• Example: 5487 → (7) + sum(548)
Step 2: Define the Base Case
• If n is a single-digit number, return n (smallest subproblem).
• Base case: if (n < 10) return n;
Step 3: Write the Recursive Case
• Extract the last digit using n % 10.
• Call the function recursively for n / 10.
Solution 1: Basic Recursion
#include <stdio.h>
int sumOfDigits(int n)
{
if (n < 10) // Base case
return n;
return (n % 10) + sumOfDigits(n / 10); // Recursive case
int main()
int num = 1234;
printf("Sum of digits of %d is: %d\n", num, sumOfDigits(num));
return 0;
Output:
Sum of digits of 1234 is: 10
✔ How It Works?
sumOfDigits(1234) = 4 + sumOfDigits(123)
sumOfDigits(123) = 3 + sumOfDigits(12)
sumOfDigits(12) = 2 + sumOfDigits(1)
sumOfDigits(1) = 1 (Base case)
Final result: 4 + 3 + 2 + 1 = 10
Key Takeaways for Problem-Solving Using Recursion
Break down the problem into smaller subproblems.
Define a base case to prevent infinite recursion.
Use recursive calls to solve the problem step by step.
Test with small inputs before applying to large numbers.
Conclusion
• Recursion is useful for dividing problems into smaller subproblems.
• Always define a base case to stop infinite recursion.
• Tail recursion is more efficient than non-tail recursion.
Here are five problems for each type of recursion, along with hints on how to solve them.
1. Direct Recursion Problems
(Function directly calls itself)
1. Factorial of a number (n!)
2. Sum of first N natural numbers
3. Reverse a number
o Problem: Given 1234, return 4321.
o Hint: Extract last digit and append recursively.
4. Power function xnx^nxn
5. Greatest Common Divisor (GCD) of two numbers
o Problem: Find GCD(48, 18).
2. Indirect Recursion Problems
(One function calls another function, which calls the first one back)
1. Check if a number is even or odd
o Hint: isEven(n) calls isOdd(n-1) and vice versa.
2. Print alternate numbers from N to 1
o Hint: printEven(n) prints n and calls printOdd(n-1), and vice versa.
3. Convert decimal to binary
o Hint: Function A extracts digits, Function B prints.
4. Find Fibonacci using two functions
o Hint: One function handles even indices, another handles odd.
5. String palindrome check using two functions
o Hint: One function compares left-to-right, another right-to-left.
3. Tail Recursion Problems
(Recursive call is the last operation before returning)
1. Factorial (Tail Recursion Version)
o Hint: Instead of return n * factorial(n-1), pass result * n.
2. Sum of first N natural numbers
o Hint: Pass accumulated sum as an argument.
3. Find the Nth Fibonacci number
o Hint: Pass prev and current as arguments.
4. Greatest Common Divisor (GCD) (Tail Recursion Version)
o Hint: Instead of return GCD(b, a % b), modify arguments.
5. Print numbers from N to 1
o Hint: Print n and call f(n-1).
4. Non-Tail Recursion Problems
(Operations exist after the recursive call)
1. Print numbers from 1 to N
o Hint: print(n-1) before printing n.
2. Reverse a string
o Hint: Print the last character after recursion.
3. Compute power function xnx^nxn
o Hint: Compute result from power(x, n-1) then multiply by x.
4. Binary Search using Recursion
o Hint: Check mid, then search in half of the array.
5. Convert decimal to binary
o Hint: Print remainder after recursion.