CSE NotesCSE Notes
Simplifying Complexity

recursive function

In C, recursive functions work similarly to those in other programming languages. A recursive function is one that calls itself to solve a problem. Here’s a general structure for a recursive function in C:

Basic Recursive Function Structure

#include <stdio.h>

// Function declaration
int recursive_function(int n);

int main() {
    int number = 5;
    printf("The factorial of %d is %d\n", number, recursive_function(number));
    return 0;
}

// Recursive function definition
int recursive_function(int n) {
    // Base case: When n is 0, return 1
    if (n == 0)
        return 1;
    else
        // Recursive case: Call the function again with n-1
        return n * recursive_function(n - 1);
}

Explanation:

  1. Base Case: The function has a condition to stop the recursion. In the example above, the base case is when n == 0. At this point, the function will return 1, and no further recursive calls will be made.
  2. Recursive Case: The function calls itself with a smaller problem (in this case, n - 1). This gradually reduces the problem size until it reaches the base case.

Example: Factorial Calculation

The recursive function above calculates the factorial of a number n. The factorial of a number n (denoted n!) is the product of all integers from 1 to n:

  • 5! = 5 * 4 * 3 * 2 * 1 = 120
  • 4! = 4 * 3 * 2 * 1 = 24
  • And so on…

Step-by-Step Example (for n = 5):

  • recursive_function(5) calls recursive_function(4)
  • recursive_function(4) calls recursive_function(3)
  • recursive_function(3) calls recursive_function(2)
  • recursive_function(2) calls recursive_function(1)
  • recursive_function(1) calls recursive_function(0) (base case reached)
  • recursive_function(0) returns 1
  • The function then returns: 1 * 1, 2 * 1, 3 * 2, 4 * 6, and finally 5 * 24 = 120

Output:

The factorial of 5 is 120

Recursive Function to Calculate Fibonacci Sequence

Here’s another example of recursion to calculate the Fibonacci sequence in C. The Fibonacci sequence starts with 0 and 1, and each subsequent number is the sum of the two preceding ones.

#include <stdio.h>

// Function declaration
int fibonacci(int n);

int main() {
    int n = 6;
    printf("The %dth Fibonacci number is %d\n", n, fibonacci(n));
    return 0;
}

// Recursive function to find Fibonacci number
int fibonacci(int n) {
    // Base cases
    if (n == 0)
        return 0;
    if (n == 1)
        return 1;
    else
        // Recursive case: Fibonacci(n) = Fibonacci(n-1) + Fibonacci(n-2)
        return fibonacci(n - 1) + fibonacci(n - 2);
}

Explanation:

  • Base Cases: The first two numbers of the Fibonacci sequence are defined as fibonacci(0) = 0 and fibonacci(1) = 1.
  • Recursive Case: For all other numbers, fibonacci(n) = fibonacci(n-1) + fibonacci(n-2).

Output:

The 6th Fibonacci number is 8

Potential Issues with Recursion in C:

  1. Stack Overflow: Like other programming languages, if recursion goes too deep, it can cause a stack overflow (e.g., when the function makes too many calls without reaching the base case).
  2. Performance Issues: Recursive algorithms can be inefficient if the same calculations are repeated many times, like in the Fibonacci example above, where fibonacci(n-1) and fibonacci(n-2) are recalculated multiple times. This can be optimized using memoization or an iterative approach.

Example of Optimized Fibonacci with Memoization:

#include <stdio.h>

#define MAX 100
int memo[MAX];

// Function declaration
int fibonacci(int n);

int main() {
    for (int i = 0; i < MAX; i++) {
        memo[i] = -1;  // Initialize memoization array to -1
    }

    int n = 6;
    printf("The %dth Fibonacci number is %d\n", n, fibonacci(n));
    return 0;
}

// Recursive Fibonacci with memoization
int fibonacci(int n) {
    // Base cases
    if (n == 0) return 0;
    if (n == 1) return 1;
    
    // Check if value already computed
    if (memo[n] != -1)
        return memo[n];

    // Recursive case with memoization
    memo[n] = fibonacci(n - 1) + fibonacci(n - 2);
    return memo[n];
}

This version stores computed Fibonacci values in a memo array to avoid redundant calculations, significantly improving performance.

Conclusion:

In C, recursive functions are powerful tools for solving problems, but they need to be carefully designed to avoid issues like stack overflow and inefficiency. The key elements are having a proper base case and ensuring that the function converges toward it with each recursive call.