0% found this document useful (0 votes)
15 views8 pages

Recursion_Recap

Recursion is a programming technique where a function calls itself to solve problems by breaking them into smaller sub-problems, involving key components such as base and recursive cases. Examples include calculating factorials, Fibonacci sequences, and summing digits, with comparisons made to iterative approaches regarding memory efficiency. Common recursive problems include binary search, string reversal, and finding the maximum element in an array, with debugging tips provided for common issues like stack overflow and infinite recursion.

Uploaded by

studymania943
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views8 pages

Recursion_Recap

Recursion is a programming technique where a function calls itself to solve problems by breaking them into smaller sub-problems, involving key components such as base and recursive cases. Examples include calculating factorials, Fibonacci sequences, and summing digits, with comparisons made to iterative approaches regarding memory efficiency. Common recursive problems include binary search, string reversal, and finding the maximum element in an array, with debugging tips provided for common issues like stack overflow and infinite recursion.

Uploaded by

studymania943
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Recap - Recursion

Recursion is a technique in programming where a function calls itself directly or indirectly to


solve a problem. It’s a powerful tool that simplifies complex problems by breaking them down
into smaller, more manageable sub-problems.

Key Components of Recursion:

● Base Case: This is the condition under which the recursive function stops calling itself.
Without a base case, the recursion would continue indefinitely, leading to a stack
overflow.
● Recursive Case: This is the part of the function where it continues to call itself with a
modified argument, gradually reducing the problem size.

Example 1: Factorial

Factorial of a number n is defined as the product of all positive integers less than or equal to n.
Mathematically, n! = n * (n-1) * (n-2) * ... * 1.

In terms of recursion:

● Base Case: factorial(0) = 1 or factorial(1) = 1


● Recursive Case: factorial(n) = n * factorial(n - 1)

Here’s how you can implement it in C:

#include <stdio.h>

int factorial(int n) {
if (n == 0 || n == 1) { // Base Case
return 1;
}
return n * factorial(n - 1); // Recursive Case
}

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

Example 2: Fibonacci Sequence


The Fibonacci sequence is a series of numbers where each number is the sum of the two
preceding ones. The sequence starts as 0, 1, 1, 2, 3, 5, 8, ...

In terms of recursion:

● Base Case: fibonacci(0) = 0, fibonacci(1) = 1


● Recursive Case: fibonacci(n) = fibonacci(n-1) + fibonacci(n-2)

#include <stdio.h>

int fibonacci(int n) {
if (n == 0) return 0; // Base Case 1
if (n == 1) return 1; // Base Case 2
return fibonacci(n - 1) + fibonacci(n - 2); // Recursive Case
}

int main() {
int num = 7;
printf("Fibonacci of %d is %d\n", num, fibonacci(num));
return 0;
}

While recursion makes the Fibonacci sequence easy to understand, it's not efficient due to
repeated calculations, which we'll discuss later.

Example 3: Sum of Digits

This function adds all the digits of a given number. For example, the sum of digits of 123 is 1 + 2
+ 3 = 6.

● Base Case: If the number is 0, the sum is 0.


● Recursive Case: sumOfDigits(n) = (n % 10) + sumOfDigits(n / 10)

#include <stdio.h>

int sumOfDigits(int n) {
if (n == 0) { // Base Case
return 0;
}
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;
}

Recursion vs. Iteration

● Recursion: It’s often more elegant and concise for problems that naturally fit a recursive
structure. However, recursion can lead to higher memory usage due to the function call
stack.
● Iteration: Iterative solutions are usually more memory-efficient because they don’t
involve the overhead of multiple function calls. However, they can sometimes be less
intuitive, especially for problems like tree traversals or permutations.

Example: Factorial

Let’s compare the recursive and iterative approaches to calculating the factorial of a number.

Recursive:

int factorial(int n) {
if (n == 0 || n == 1) {
return 1;
}
return n * factorial(n - 1);
}

Iterative:

int factorialIterative(int n) {
int result = 1;
for(int i = 2; i <= n; i++) {
result *= i;
}
return result;
}

When to Use Recursion?

● Use recursion when the problem can naturally be divided into similar sub-problems.
● Avoid recursion if it leads to excessive memory use or stack overflow.

Common Recursive Problems

Problem 1: Binary Search

Binary Search is an efficient algorithm for finding an element in a sorted array. It works by
repeatedly dividing the search interval in half.

Algorithm:

1. Compare the target value with the middle element of the array.
2. If the target value matches the middle element, the search is done.
3. If the target value is less than the middle element, search in the left half.
4. If the target value is greater than the middle element, search in the right half.

#include <stdio.h>

int binarySearch(int arr[], int low, int high, int x) {


if (high >= low) {
int mid = low + (high - low) / 2;
if (arr[mid] == x) return mid;
if (arr[mid] > x) return binarySearch(arr, low, mid - 1, x);
return binarySearch(arr, mid + 1, high, x);
}
return -1; // Element not found
}

int main() {
int arr[] = {2, 3, 4, 10, 40};
int n = sizeof(arr) / sizeof(arr[0]);
int x = 10;
int result = binarySearch(arr, 0, n - 1, x);
(result == -1) ? printf("Element is not present in array\n") : printf("Element is present at index %d\n",
result);
return 0;
}

Problem 2: String Reversal


Reversing a string is a common problem where recursion can be used effectively. The idea is to
swap the characters from the ends of the string moving inward.

#include <stdio.h>

void reverseString(char str[], int start, int end) {


if (start >= end) return; // Base Case
char temp = str[start];
str[start] = str[end];
str[end] = temp;
reverseString(str, start + 1, end - 1); // Recursive Case
}

int main() {
char str[] = "recursion";
reverseString(str, 0, sizeof(str) - 2); // -2 to exclude the null character
printf("Reversed string is %s\n", str);
return 0;
}

Problem 3: Find the Maximum Element in an Array

Finding the maximum element in an array can also be done recursively by comparing the
current element with the maximum of the rest of the array.

#include <stdio.h>

int findMax(int arr[], int n) {


if (n == 1) return arr[0]; // Base Case
int maxOfRest = findMax(arr, n - 1); // Recursive Case
return (arr[n-1] > maxOfRest) ? arr[n-1] : maxOfRest;
}

int main() {
int arr[] = {12, 10, 30, 50, 100, 40};
int n = sizeof(arr) / sizeof(arr[0]);
printf("The maximum element is %d\n", findMax(arr, n));
return 0;
}

Debugging Recursive Code

Common Issues:
● Stack Overflow: This occurs when the recursion depth is too deep. It’s a common issue
in recursion when the base case is not properly defined or when the problem size
doesn’t reduce sufficiently with each recursive call.

● Infinite Recursion: Happens if there’s no proper base case or if the recursive case
doesn’t converge towards the base case. This leads to the function calling itself
indefinitely.

Tips for Debugging


Print Statements: Use print statements inside the recursive function to trace the function calls
and understand the flow of recursion.

Example: In the factorial function, you can print the current value of n before each recursive call
to see the sequence of calls:

int factorial(int n) {
printf("Calling factorial(%d)\n", n);
if (n == 0 || n == 1) {
return 1;
}
return n * factorial(n - 1);
}

● Base Case Verification: Always double-check that your base case is correct and that it
will be reached in every possible execution path. This is critical for preventing infinite
recursion.

● Test with Simple Cases: Start testing your recursive functions with the simplest
possible cases (e.g., the base case) to ensure that your function handles them correctly.

● Dry Run: Manually trace through the recursive function with a small input to see if it
behaves as expected. This helps you understand how the function evolves with each
recursive call.

● Use a Debugger: If your environment supports it, use a debugger to step through the
recursive calls and examine the state of variables at each step.

Practice Problems
Problem 1: Calculate the Power of a Number

Write a recursive function to calculate the power of a number x^n. The function should take two
arguments, the base x and the exponent n.

Example:

Input: x = 2, n = 3

Output: 8

Hint: Use the relation x^n = x * x^(n-1).

Problem 2: Palindrome Check

Write a recursive function to check if a string is a palindrome. A palindrome is a word that reads
the same backward as forward.

Example:

Input: str = "madam"

Output: "madam" is a palindrome

Hint: Compare the first and last characters of the string, then recursively check the substring
that excludes these characters.

Problem 3: GCD of Two Numbers

Write a recursive function to find the greatest common divisor (GCD) of two numbers using
Euclid's algorithm.

Example:

Input: a = 48, b = 18

Output: 6

Hint: Use the relation GCD(a, b) = GCD(b, a % b).

Problem 4: Recursive Sum of an Array


Write a recursive function that calculates the sum of all elements in an array.

Example:

Input: arr = [1, 2, 3, 4, 5]

Output: 15

Hint: Sum the first element with the sum of the remaining elements.

Problem 5: Generate All Subsets of a Set

Write a recursive function to generate all possible subsets of a given set of integers. This is a
classic problem often referred to as the "power set" problem.

Example:

Input: set = {1, 2, 3}

Output: { {}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3} }

Hint: For each element in the set, you can either include it in a subset or exclude it, leading to a
recursive exploration of both possibilities.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy