












Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
The concept of recursion in programming through a pseudocode example of a problem-solving function. It also compares recursion with iteration and provides examples of recursive and iterative solutions for factorial and exponentiation. Understand the nature of recursion, how to trace a recursive function, and the advantages and disadvantages of recursion.
Typology: Exams
1 / 20
This page cannot be seen from the preview
Don't miss anything!













Recursion is a powerful problem-solving strategy. Solves large problems by reducing them to smaller problems of the same form. The subproblems have the same form as the original problem. To illustrate the basic idea, imagine you have been appointed as funding coordinator for a large charitable organization. Your job is to raise one million dollars in contributions to meet the expenses of the organization. If somebody can write out a check for the entire amount, your job is easy. On the other hand, it may not be easy to locate persons who would be willing to donate one million dollars. However people don’t mind donating smaller amounts. If lets say $100 is a good enough amount, than all you have to do is to call 10,000 friends to complete the task. Well, it is going to be a tall order for you, but you know that your organization has a reasonable supply of volunteers across the country. You may start off by finding 10 dedicated supporters in different parts of the country and appoint them regional coordinators. So each person now has to raise $100,000. It is simpler than raising one million, but hardly qualifies to be easy. Maybe they can adopt the same strategy, i.e. delegate parts of the job to 10 volunteers each within their region and asking each to raise $10,000. The delegation process can continue until there are volunteers who have to go around raising donations of $100 each from individual donors. The following structure is a psuedocode for the problem: Ask funding coordinator to collect fund void collect (int fund) { if ( fund <=100) { contact individual donor. } else { find 10 volunteers. Get each volunteer to collect fund/10 dollars Pool the money raised by the volunteers. } }
To make sure the process stops at some point, we define 0! to be 1. Thus the conventional mathematical definition looks like this: n! = 1 if n = 0 n! = n*(n-1)! if n > 0 This definition is recursive , because it defines the factorial of n in terms of factorial of n – 1. The new problem has the same form, which is, now find factorial of n – 1. In C: int fact(int n) { if (n ==0) return (1); else return (n * fact(n-1)); }
The Nature of Recursion
Because n is 0, the function parameter can return its result by executing the statement return(1); The value 1 is returned to the calling frame, which now becomes the top of stack as shown: Main fact1 fact2 fact3 fact if (n ==0) return (1); else return (n * factorial(n-1)); value 1 n = 1 Now the computation proceeds back through each of recursive calls. In above frame n=1 so it returns the value 1 to its caller , now the top frame shown here: Main fact1 fact2 fact if (n ==0) return (1); else return (n * factorial(n-1)); value 1 n = Because n is 2, a value 2 is passed back to previous level: Main fact1 fact if (n ==0) return (1); else return (n * factorial(n-1)); value 2 n = 3 Now the value returned is 3 x 2 to previous level as shown:
Main fact if (n ==0) return (1); else return (n * factorial(n-1)); value 6 n = 4 Finally the value 4 x 6 is calculated at 24 is returned to the main program.
Raising an integer to a power (which is also an integer) involves successive multiplication by the base. However, as the result becomes quite large very soon, it would work only if there is a machine to hold large integers. xn^ requires n-1 multiplications. power( x, n) { if ( n==0) return 1; if(n==1) return x; else return ( x * power( x , n – 1 ) ; } A more efficient iterative solution is possible. Note that a power 16 can be obtained by first computing power of 8 and multiplying the result with itself. Power of 8 can be obtained by multiplying two numbers of power of 4 each. Note the similarity with binary search. A higher power can be obtained from its lower power (i.e. power/2).
Consider the following recursive function: int puzzle (int N) { if (N == 1) return 1; if (N % 2 == 0) return (1 + puzzle(N/2)); else return (2 + puzzle(3N+1)); }* What do the following function calls evaluate to? a) puzzle(3); = return (2 + puzzle(10))
Recursive function to print a string in reverse order In the following program segment, we are trying to read a string and print it in reverse order. void print_reverse(int n) { char next; if (n == 1) { / stopping case / scanf("%c",&next); printf("%c", next); } else { scanf("%c", &next); print_reverse(n-1); printf("%c",next); } return; } int main() { printf("Enter a string: "); print_reverse(n); printf("\n"); }
Check whether a given string is a palindrome A palindrome is a string, whose first and last characters match AND the remaining substring is also a palindorme. Here is a C code which asks the user to supply a string and checks whether it is a palindrome or not. #include <stdio.h> #include <ctype.h> #include<string.h> int checkPal(char str[], int ); int main ( ) { char string[20] ; printf("\n Enter a string\n"); scanf("%s", string); if ( checkPal (str, strlen (str) )) printf("\nyes, it is a palindrome\n"); else printf("\nNo, it is not a palindrome"); } /function checkPal returns 1 if remaining characters in array str form a palindrome. / int checkPal ( char str[], int len) { if ( len <= 1) { return ( 1) ; } else { return ( (str [0] == str [ len - 1 ] ) && checkPal(str + 1, len - 2 ) ); } / array arithmetic used. New substring begins at str+1 and length chosen is 2 less than current length / }
Binary search ( recursive version) Divide and conquer implementation #include <stdio.h> int findkey (int key, int array[], int n ); int binary ( int key, int array [ ], int low, int high); int main ( ) { int key,check; int arrayd[11] = {12,24,30,45,51,65,70,76,82,91,96}; printf("\n Enter target key\n"); scanf("%d",&key); check= findkey(key,arrayd,11); if (check > -1) printf("\nyes, key found\n"); else printf("\nNo, not found\n"); } int findkey ( int key, int array[], int n ) { int temp; temp = binary(key, array, 0, n-1) ; return temp ; } int binary ( int key, int array [ ], int low, int high) { int mid; if ( low > high ) return (-1 ); mid = ( low + high )/ 2; printf("\nmid=%d\n",mid); if ( key == array [mid] ){ return (mid);} if ( key < array [mid]) { return (binary (key, array, low, mid - 1 )); } else { return (binary (key, array, mid + 1, high )) ; } }
It has a small history. In 1202, Italian mathematician Leonardo Fibonacci posed a problem that has had a wide influence on many fields. The problem is related to growth in population of rabbits, generation to generation. The rabbits are reproduced according to the following rules:
(2/3) (3/2) ( 3/2)n-
(2/3) ( 3/2)n
[(2/3) + (4/9) ] ( 3/2)n (10/9) ( 3/2)n tn > ( 3/2)n In C: int fibonacci(int n) { if (n < 2) return n; else return(fibonacci(n-2) + fibonacci(n-1)); } Calling the function : x = fibonacci(5); What is the complexity of this function? At every call , two more fibonacci functions are being called. Let T(n) be running time for calling the fib. Function. For n =0 or 1 it takes constant time T(0) = T(1) = 1 At any other stage, it involves calling fib function with running time T(n-1) and again with running time T(n-2). In addition, there is a “if” operation and one “addition” operation. Thus, T(n) = T(n-1) + T(n-2) + 2 Since fib (n) = fib (n-1) + fib (n-2) it is easy to see that T(n) > fib(n)
power( x, n) { if ( n==0) return 1; if(n==1) return x; if (n is even) return power ( x * x, n / 2); else return power( x * x, n / 2 ) * x ; } At every step the problem size reduces to half the size. When the power is an odd number, an additional multiplication is involved. To work out time complexity , let us consider the worst case, i.e. at every step an additional multiplication is needed. T(n) = T(n/2) + 1 = [ T(n/4) + 1 ] + 1 = [ T(n/8) + 1 ] + 1 + 1 = T( n/ 2^3 ) + 3
....... ....... = T( n/ 2k) + k Choosing 2 k= n T(n) = log n + 1 Thus the order of complexity is O( log n) LOGARTHIMIC TIME
Common Errors in Recursive Formulations
Comparison of Iteration and Recursion