17A. Duplicated Recursive Calls

In terms of algorithm efficiency, recursion is an amplifier. If you do something that is a little bit good, recursion can amplify that to make it very good. But the flip side is that, if you do something a little bad, recursion amplifies it and makes it very bad.

To illustrate, suppose that you have an array A of integers of size n (where n > 0), and you want to find the largest value in the array.

  1. If n = 1, then the largest value is just A[0].

  2. If n > 1 then the largest value is the larger of A[n−1] and the largest of the first n−1 values in the array.

Here is a definition of largest for consideration.

  // largest(A,n) yields the largest of
  // A[0], A[1], ..., A[n-1].

  int largest(const int A[], const int n)
  {
    if(n == 1)
    {
      return A[0];
    }
    else if(A[n-1] > largest(A, n-1))
    {
      return A[n-1];
    }
    else
    {
      return largest(A, n-1);
    }
  }
That will compute the correct answer, but it is very slow. The problem is that, when largest(A, n−1) > A[n−1], this function computes largest(A, n−1) twice, once in the test and once in the return statement.

Recursion amplifies that. If the largest value in the array is in A[0], then this function takes at least 2n steps to find the largest value. If n = 200, then 2n is much larger than the number of protons in the earth! The reason for this bad behavior is below.

It is easy to fix the problem. Just make sure not to compute largest(A, n−1) more than once.

  // largest(A,n) yields the largest of
  // A[0], A[1], ..., A[n-1].

  int largest(int A[], int n)
  {
    if(n == 1)
    {
      return A[0];
    }
    else
    {
      return max(A[n-1], largest(A, n-1));
    }
  }

Why is the original algorithm for largest so slow? Imagine that the largest value is in A[0]. Then the last case is taken for all values of n > 1. Let's show a computation of largest(A, 100) in a tree diagram. Each node in the tree represents a call to largest. (L stands for largest.)

Each level in the tree has twice as many nodes as the level above it. There are 299 nodes in the level whose nodes say L(A, 1).

299 is, very roughly, 1,000,000,000,000,000,000,000,000,000,000.