C Programs Tutorials | IT Developer
IT Developer

C Programming - C Recursion



Share with a Friend

C Programming - C Recursion

C Recursion

Recursion is a programming technique where a function calls itself in order to solve a problem. In C, a function can call itself directly or indirectly to break down a complex problem into smaller, more manageable sub-problems. Each recursive call typically brings the problem closer to a base case, at which point the recursion stops.

Key Components of Recursion

  1. Base Case: The condition that stops the recursion. Without a base case, recursion would continue indefinitely, leading to a stack overflow error.
  2. Recursive Case: The part of the function where it calls itself to solve a smaller version of the problem.

Syntax of a Recursive Function

A recursive function has the following general structure:

C

return_type function_name(parameters) {

    // Base case: If the condition is met, return a value

    if (base_case_condition) {

        return base_value;

    }

    else {

        // Recursive case: Call the function with modified parameters

        return function_name(modified_parameters);

    }

}

Example 1: Factorial of a Number Using Recursion

The factorial of a number n is the product of all positive integers less than or equal to n. For example:

  • factorial(5) = 5 * 4 * 3 * 2 * 1 = 120

C

#include <stdio.h>

 

// Function to calculate the factorial of a number

int factorial(int n) {

    // Base case: factorial of 0 or 1 is 1

    if (n == 0 || n == 1) {

        return 1;

    }

    else {

        // Recursive case: factorial(n) = n * factorial(n-1)

        return n * factorial(n - 1);

    }

}

 

int main() {

    int num = 5;

    int result = factorial(num);  // Calling the recursive factorial function

    printf("Factorial of %d is %d\n", num, result);  // Printing the result

    return 0;

}

Explanation:

  • The function factorial calls itself with a smaller argument (n - 1) until it reaches the base case (n == 0 or n == 1).
  • When the base case is reached, the function starts returning values back through the recursive calls.

Output:

Factorial of 5 is 120

Example 2: Fibonacci Series Using Recursion

The Fibonacci series is a sequence of numbers where each number is the sum of the two preceding ones, starting from 0 and 1:

  • F(0) = 0
  • F(1) = 1
  • F(n) = F(n-1) + F(n-2) for n >= 2

C

#include <stdio.h>

 

// Function to calculate the nth Fibonacci number

int fibonacci(int n) {

    // Base cases

    if (n == 0) {

        return 0;

    }

    else if (n == 1) {

        return 1;

    }

    else {

        // Recursive case: F(n) = F(n-1) + F(n-2)

        return fibonacci(n - 1) + fibonacci(n - 2);

    }

}

 

int main() {

    int num = 6;

    printf("Fibonacci of %d is %d\n", num, fibonacci(num));  // Calling the recursive fibonacci function

    return 0;

}

Explanation:

  • The function fibonacci calls itself recursively to calculate the Fibonacci number for a given n. It stops when it reaches the base cases (n == 0 or n == 1).
  • The Fibonacci function performs repeated calculations, so it is not efficient for larger n due to overlapping sub-problems.

Output:

Fibonacci of 6 is 8

Advantages of Recursion

  1. Simplicity: Recursion provides a simple and clean solution for problems that are naturally recursive (e.g., tree traversal, factorials, Fibonacci series).
  2. Code Reduction: Recursive solutions often require fewer lines of code compared to their iterative counterparts.
  3. Problem Decomposition: Recursion breaks down complex problems into simpler sub-problems, making them easier to understand and solve.

Disadvantages of Recursion

  1. Performance Issues: Recursion can be inefficient, especially if the function makes redundant calls (e.g., Fibonacci). In such cases, it may result in a stack overflow due to excessive function calls.
  2. Memory Overhead: Each recursive call consumes memory for storing local variables and the return address, which can lead to higher memory usage.
  3. Slower Execution: Recursive functions tend to have slower execution due to the overhead of function calls, especially for large inputs.

Tail Recursion

In tail recursion, the recursive call is the last operation in the function, which allows certain optimizations by the compiler to reduce memory usage. Tail recursion can be more efficient because the compiler can reuse the current function's stack frame, instead of creating a new one for each recursive call.

Here is an example of a tail-recursive function for factorial:

C

#include <stdio.h>

 

// Tail recursive function to calculate factorial

int factorial_tail_recursive(int n, int result) {

    // Base case: when n reaches 0

    if (n == 0) {

        return result;

    }

    // Tail recursion: multiply and call recursively with updated result

    return factorial_tail_recursive(n - 1, n * result);

}

 

int main() {

    int num = 5;

    int result = factorial_tail_recursive(num, 1);  // Initial result is 1

    printf("Factorial of %d is %d\n", num, result);

    return 0;

}

Explanation:

  • The tail-recursive factorial_tail_recursive function computes the factorial, passing the accumulated result as an argument.
  • The recursion terminates when n becomes 0, and the final result is returned directly.

Output:

Factorial of 5 is 120

Conclusion

  • Recursion is a powerful concept in C programming, particularly useful for problems that have a recursive structure (like factorials, Fibonacci numbers, and tree traversal).
  • It involves a function calling itself, with a base case to stop the recursion.
  • While recursion simplifies the code for some problems, it should be used carefully to avoid performance issues and stack overflow.