COMP2521 ♢ Recursion ♢ (23T1)

COMP2521(23T1) ♢ Recursion ♢ [0/10]
❖ Recursion


Recursion is a powerful problem-solving strategy

It is related to induction in mathematics, which has
COMP2521(23T1) ♢ Recursion ♢ [1/10]
❖ Example #1: factorial

A simple example: computing factorial (n!)

E.g.


factorial(3) = 3 * factorial(2)
             = 3 * (2 * factorial(1))
             = 3 * (2 * 1) = 6

COMP2521(23T1) ♢ Recursion ♢ [2/10]
❖ ... Example #1: factorial

Expressing this as a C function:

int factorial(int n) {
   if (n == 1)   // base case
      return 1;
   else          // recursive case
      return n * factorial(n-1);
}

compared to iterative version

int factorial(int n) {
   int fac = 1;
   for (int i = 1; i <= n; i++)
      fac = fac * i;
   return fac;
}

COMP2521(23T1) ♢ Recursion ♢ [3/10]
❖ Example #2: Summing values in a list

Another simple example: summing integer values in a list

E.g.


sum [1,2,3] = 1 + sum [2,3]
            = 1 + (2 + sum [3])
            = 1 + (2 + (3 + sum []))
            = 1 + (2 + (3 + 0)) = 6

COMP2521(23T1) ♢ Recursion ♢ [4/10]
❖ ... Example #2: Summing values in a list

Expressing previous method as an (abstract) function

int sum(List L) {
   if (empty(L))
      return 0;
   else {
      int first, sumRest;
      first = head(L);
      sumRest = sum(tail(L));
      return first + sumRest;
   }
}

COMP2521(23T1) ♢ Recursion ♢ [5/10]
❖ ... Example #2: Summing values in a list

And then expressing using typical list data structure:

struct Node { int val; struct Node *next; };

int sum(struct Node *L) {
   if (L == NULL)
      return 0;
   else {
      int first, sumRest;
      first = L->val;
      sumRest = sum(L->next);
      return first + sumRest;
   }
}

or

int sum(struct Node *L) {
   if (L == NULL)
      return 0;
   else
      return L->val + sum(L->next);
}

COMP2521(23T1) ♢ Recursion ♢ [6/10]
❖ How it works

Recursion is a function calling itself

Won't the system get confused?

No, because each call to the function is a separate instance

The "mini-environments" are called stack frames
COMP2521(23T1) ♢ Recursion ♢ [7/10]
❖ ... How it works


How the memory state changes during execution

[Diagram:Pics/fac-stack.png]


fac(3) calls fac(2) calls fac(1) returns 1 returns 2*1 returns 3*2 returns 6

COMP2521(23T1) ♢ Recursion ♢ [8/10]
❖ Using Recursion

While it is useful to know how it works ...

Sometimes it is confusing to think about stacks, etc.

When designing (or reading) recursive functions

COMP2521 has many examples of recursively-defined algorithms
COMP2521(23T1) ♢ Recursion ♢ [9/10]
❖ Postscript

Generally, recursive solutions are efficient (except stack space)

Sometimes, they can be very inefficient, e.g.

// returns n'th fibonacci number
int fibonacci(int n) {
   if (n == 1)
      return 1;
   else if (n == 2)
      return 1;
   else
      return fibonacci(n-1) + fibonacci(n-2);
}

Trace the recursive calls for fibonacci(5) to see the problem

COMP2521(23T1) ♢ Recursion ♢ [10/10]


Produced: 12 Feb 2023