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.