What is Recursion?
The process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called as recursive function. Using recursive algorithm, certain problems can be solved quite easily. Examples of such problems are Towers of Hanoi (TOH), Inorder/Preorder/Postorder Tree Traversals, DFS of Graph, etc.What is the base condition in recursion?
In a recursive program, the solution to the base case is provided and the solution of bigger problem is expressed in terms of smaller problems.int fact(int n)In the above example, the base case for n < = 1 is defined and a larger value of a number can be solved by converting to a smaller one till the base case is reached.
{
if (n < = 1) // base case
return 1;
else
return n*fact(n-1);
}
How a particular problem is solved using recursion?
The idea is to represent a problem in terms of one or more smaller problems, and add one or more base conditions that stop recursion. For example, we compute factorial n if we know factorial of (n-1). The base case for factorial would be n = 0. We return 1 when n = 0.int fact(int n)If fact(10) is called, it will call fact(9), fact(8), fact(7), and so on but the number will never reach 100. So, the base case is not reached. If the memory is exhausted by these functions on the stack, it will cause a stack overflow error.
{
// wrong base case (it may cause
// stack overflow).
if (n == 100)
return 1;
else
return n*fact(n-1);
}
How memory is allocated to different function calls in recursion?
When any function is called from main(), the memory is allocated to it on stack. A recursive function calls itself, the memory for the called function is allocated on top of memory allocated to the calling function and a different copy of local variables is created for each function call. When the base case is reached, the function returns its value to the function by whom it is called and memory is de-allocated and the process continues.void printFun(int test)Output :
{
if (test < 1)
return;
else
{
print test;
printFun(test-1); // statement 2
print test;
return;
}
}
// Calling function printFun()
int test = 3;
printFun(test);
3 2 1 1 2 3
array[] = {1, 2, 3, 4, 5}
X = 3.
The function should return True, as 3 is
present in the array.
// arr[] is the given array
// l is the lower bound in the array
// r is the upper bound
// x is the element to be searched for
// l and r defines that search will be
// performed between indices l to r
bool recursiveSearch(int arr[], int l,
int r, int x)
{
if (r < l)
return false;
if (arr[l] == x)
return true;
if (arr[r] == x)
return true;
return recursiveSearch(arr, l + 1,
r - 1, x);
}
Input : string = "malayalam"
Output : Yes
Reverse of malayalam is also
malayalam.
Input : string = "max"
Output : No
Reverse of max is not max.
// s and e defines the start and end index of string
bool isPalindrome(char str[], int s, int e)
{
// If there is only one character
if (s == e)
return true;
// If first and last
// characters do not match
if (str[s] != str[e])
return false;
// If there are more than
// two characters, check if
// middle substring is also
// palindrome or not
if (s < e)
return isPalindrome(str, s + 1, e - 1);
return true;
}
5 4 3 2 1
Which one is Better-Tail Recursive or Non Tail-Recursive?
The tail-recursive functions are considered better than non-tail recursive functions as tail-recursion can be optimized by the compiler. The idea used by compilers to optimize tail-recursive functions is simple, since the recursive call is the last statement, there is nothing left to do in the current function, so saving the current function’s stack frame is of no use.Can a non-tail recursive function be written as tail-recursive to optimize it?
Consider the following function to calculate factorial of N. Although it looks like Tail Recursive at first look, it is a non-tail-recursive function. If we take a closer look, we can see that the value returned by fact(N-1) is used in fact(N), so the call to fact(N-1) is not the last thing done by fact(N).int fact(int N)
{
if (N == 0)
return 1;
return N*fact(N-1);
}
int factTR(int N, int a)
{
if (N == 0)
return a;
return factTR(N-1, N*a);
}
Input : set = "abc"
Output : "". "a", "b", "c", "ab", "ac", "bc", "abc"
Input : set = "abcd"
Output : "" "a" "ab" "abc" "abcd" "abd" "ac" "acd"
"ad" "b" "bc" "bcd" "bd" "c" "cd" "d"
abc
ab
ac
a
bc
b
c
josephus(n, k) = (josephus(n - 1, k) + k-1) % n + 1How does this recursion work? When we kill k-th person, n-1 persons are left, but numbering starts from k+1 and goes in modular way.
josephus(1, k) = 1
Input : str = "ABC"
Output : ABC ACB BAC BCA CAB CBA
Idea: We iterate from first to last index. For every index i, we swap the i-th character with the first index. This is how we fix characters at the current first index, then we recursively generate all permutations beginning with fixed characters (by parent recursive calls). After we have recursively generated all permutations with the first character fixed, then we move the first character back to its original position so that we can get the original string back and fix the next character at first position.
ABC ACB BAC BCA CBA CAB