C Que 4
C Que 4
1. Definition of Recursion
Recursion is a programming technique in which a function calls itself directly or indirectly in order
to solve a problem. The function performs a small part of the problem, and then delegates the
remaining part to itself until it reaches a base condition where it stops calling itself.
In simpler terms, recursion is when a function solves a problem by solving smaller instances of the
same problem.
2. Types of Recursion
• Direct Recursion: When a function calls itself directly. Example:
void function() {
function(); // Direct call to itself
}
• Indirect Recursion: When a function calls another function, and that function, in turn, calls
the original function. Example:
void functionB(); // forward declaration
void functionA() {
functionB(); // Calls functionB
}
void functionB() {
functionA(); // Calls functionA
}
• Tail Recursion: The recursive call is the last operation in the function. It’s more optimized
by compilers. Example:
int factorial_tail(int n, int result) {
if (n == 0)
return result;
else
return factorial_tail(n - 1, n * result); // Tail recursion
}
• Non-Tail Recursion: The recursive call is not the last operation; after the recursive call,
more operations are performed. Example:
int factorial(int n) {
if (n == 0)
return 1;
else
return n * factorial(n - 1); // Non-tail recursion
}
3. Example of Recursion in C
Let's consider the famous Factorial Function and a Fibonacci Series example to demonstrate
recursion.
Factorial Function Example
The factorial of a number n is the product of all positive integers less than or equal to n.
Formula:
factorial(n) = n * factorial(n - 1)
factorial(0) = 1
#include <stdio.h>
int main() {
int num = 5;
printf("Factorial of %d is %d\n", num, factorial(num));
return 0;
}
Output:
Factorial of 5 is 120
#include <stdio.h>
int main() {
int num = 6;
printf("Fibonacci of %d is %d\n", num, fibonacci(num));
return 0;
}
Output:
Fibonacci of 6 is 8
4. Utility and Justification of Recursion
Recursion is highly useful in situations where a problem can be divided into smaller sub-problems
that resemble the original problem. It simplifies code and makes it easier to solve complex
problems. Below are some examples of problems where recursion is beneficial:
• Mathematical problems: Problems like calculating factorials, Fibonacci numbers, greatest
common divisors (GCD), etc.
• Data structures: Traversing and manipulating trees and graphs (e.g., depth-first search in
trees or graphs).
• Sorting algorithms: Recursive algorithms like quicksort and mergesort.
• Backtracking problems: Problems like solving mazes, puzzles, and games like the N-
Queens problem.
5. Advantages of Recursion
• Simplicity and Clarity: Recursion can simplify the solution to complex problems and make
the code easier to understand.
• Fewer Lines of Code: Recursive solutions often require fewer lines of code, reducing
complexity and improving readability.
• Problem Decomposition: Helps break down a complex problem into smaller, manageable
sub-problems.
6. Disadvantages of Recursion
• Memory Usage: Recursion consumes more memory due to the call stack. Each recursive
call uses additional stack space.
• Performance Overhead: Recursive calls have overhead due to the function call itself,
which might lead to inefficiency for large problems.
• Stack Overflow: If the recursion depth is too large (e.g., too many recursive calls), it can
cause a stack overflow error.
Conclusion
Recursion is a powerful tool in programming, but it must be used carefully due to its memory and
performance overheads. However, for problems that inherently have a recursive structure, recursion
offers a clear and concise solution.