18A. Recursive Search Algorithms

NextPrime

We have seen how to write scan algorithms using recursion, but what about search algorithms? Recall that we defined nextPrime(n) previously using a loop, where nextPrime(n) is the smallest prime number that is greater than n. NextPrime is easy to write recursively. If n+1 is prime, then that is the value of nextPrime(n). Otherwise, the answer is the value of nextPrime(n+1).

  int nextPrime(int n)
  {
    if(isPrime(n+1))
    {
      return n+1;
    }
    else
    {
      return nextPrime(n+1);
    }
  }

Member

Recall that we used a loop to write a definition of member(x, A, n), which returns true if at least one of the values A[0], … A[n−1] is equal to x. Let's do it using recursion. There are three cases. Each assumes that the preceding cases did not apply.

  1. Member(x, A, n) asks whether any of the first n variables in array A holds x. If n = 0, then that cannot possibly be true, since there are no values to look at.

  2. If A[n−1] = x, then yes, one of A[0], …, A[n−1] is equal to x. (Note that it is critical to handle the case where n = 0 first. If n = 0 then n−1 = −1, and there is no such thing as A[−1].)

  3. If neither of the preceding cases is applicable, then n > 0 and A[n−1] ≠ x. In that case, member(x, A, n) is true if and only if member(x, A, n−1) is true. (We can ignore A[n−1] since it is not equal to x.)

Here is a definition of member based on those observations.

  bool member(int x, int A[], int n)
  {
    if(n == 0)
    {
      return false;
    }
    else if(A[n-1] == x)
    {
      return true;
    }
    else
    {
      return member(x, A, n-1);
    }
  }

Notice that there are two base cases, one that returns true and one that returns false. That is typical (but not universal) of recursive search algorithms.

AllPositive

Carrying on the same ideas, here is a recursive definition of allPositive. Note that allPositive(A, 0) is true, since there are not any non-positive numbers among the first 0 members of array A.

  bool allPositive(int A[], int n)
  {
    if(n == 0)
    {
      return true;
    }
    else if(A[n-1] <= 0)
    {
      return false;
    }
    else
    {
      return allPositive(A, n-1);
    }
  }

Exercises

  1. Using recursion, write a definition of ascending(A, n), which returns true if A[0], … A[n−1] are in strictly ascending order, where A is an array of integers. If n = 1, the array is in ascending order by definition. Answer

  2. Write a recursive definition of anyPrime(a, b), which returns true if any of the numbers a, a + 1, … b is prime. If a > b then anyPrime(a, b) is false. Answer

  3. Function member(A, n) is defined above. Suppose that it is defined as follows instead. Does it work?

      bool member(int x, int A[], int n)
      {
        if(n == 0)
        {
          return false;
        }
        else 
        {
          return A[n-1] == x || member(x, A, n-1);
        }
      }
    
    Answer

  4. Suppose that member(A, n) is defined as follows instead. Does it work?

      bool member(int x, int A[], int n)
      {
        if(n == 0)
        {
          return false;
        }
        else 
        {
          return member(x, A, n-1) || A[n-1] == x;
        }
      }
    
    Answer