Lecture 10: Introduction to Recursion
Objectives of this lecture
q Learn what recursion is – its good and bad points
q Differentiate between recursion and iteration
q Be able to write recursive functions
What is recursion?
q So far, we have seen that a C program consists of the
function main() and zero or more other functions.
q That each of the other functions can be called by
main() or by other functions.
q The news is that C also allows a function to call
itself. Such a function is called a
recursive function.
q Recursion is essentially another way of performing
iteration.
q It is a very powerful tool for simplifying algorithms
and coding of functions that involve repetitions
q It generally involves using the divide and conquer approach
to problem solving.
q In this approach, a large problem is solved by
breaking it into two or more sub-problems and solving the sub-problems. The sub-problems are solved by further
sub-dividing them into more simpler problems.
This sub-division continue until the simples form of the problem is
obtained, the solution to which is obvious.
q Like most useful tools, recursion has its bad points
which we shall discuss in the next lecture.
Examples of recursive functions.
q Recursive functions generally consists of two parts:
Ø
Base
Case:
Which provides a solution to the simplest form of a problem.
Ø
Recursive
Case: Which solves a general form of the
problem in terms of the next simpler version of the problem.
Example 1: Factorial Function:
The factorial of a non-zero number n is defined mathematically as:
An iterative
solution to this problem is as follows:
long
fact(int n)
{ long ans=1;
int i;
for (i=n; i>1, i--)
ans*=i;
return ans;
}
Another way to
implement the factorial function is to use recursion as follows:
long
fact(int n)
{ if (n<1)
return 1;
else
return (n*fact(n-1));
}
Notice that the
recursive solution looks much more similar to the mathematical definition. It also
require less number of variables. These
makes it more easier to understand and implement than the iterative method.
The following
shows how the computer behaves when the function is called with a number, say 4:
Example 2: Power function.
The function that
returns the result of x to power a positive number n,
can be defined mathematically as:
This can be implemented recursively as
follows:
float power(float x, int n)
{ if (n<0)
return 1;
else
return (x*power(x,n-1);
}
Compare the recursive implementation with
the following iterative version:
float
power(float x, int n)
{ int i;
float p=1;
for(i=1; i<=n; i++)
p*=x;
return p;
}
Example 3: Sum of integers
The following functions prints sum of the
first n terms of the sequence:
1
+ 2 + 3 + 4 + 5 + …. + n
The recursive version:
int sumton(int n)
{ if (n ==1)
return 1;
else
return (n+sumton(n-1));
}
|
The iterative
version:
int sumton(int n)
{ int i, sum=0;
for (i=1; i<=n; i++)
sum+=i;
return sum;
}
|
Example 4: Reversing string.
An interesting feature of recursion is its
ability to easily reverse a process.
The following program reads a string from the user and prints it
backward.
#include
<stdio.h>
void
reverse_str(void);
main()
{
printf(“input a line: “);
reverse_str();
printf(“\n\n”);
return
0;
}
void
reverse_str(void)
{
char ch;
scanf(“%c”,
&ch);
if (ch != ‘\n’)
reverse_str();
printf(“%c”,ch);
}
q Notice that in the function reverse_str, if the
character read is not the new line character, the function is invoked again.
q Each call has its own local storage for the variable ch. The function calls are
stacked by the system until the new line character is read.
q Only after the new line character is read that
printing begins – starting with the last character entered.
q The iterative version of the above program would require
a character array to be declared --
left as an exercise.