4

Given an integer array a of size n, write a tail-recursive function with prototype

int f(int a[], int n);

that finds the minimum element of the array.


This is the best I managed to come up with:

int f(int a[], int n)
{
   static int *min;

   if (min == 0)
      min = new int(a[n - 1]);
   else if (*min > a[n - 1])
      *min = a[n - 1];

   if (n == 1)
      return *min;
   else
      return f(a, n - 1);
}

Can it get better? I do not like the use of a static variable.

4
  • You can do a ton better. The thing in recursion that isn't easily grasped (therefore exploited) is the use of the stack to hold temporary values along the way. Think about that for a minute. Commented Nov 28, 2012 at 1:51
  • the array isnt any sorted i gather. Commented Nov 28, 2012 at 1:51
  • 2
    @ashley that would kinda of take the fun out of it =P Commented Nov 28, 2012 at 2:21
  • @WhozCraig not as fun as seeking something drastic in an already-optimal alg. go as recursive as you like. he's been getting too much reaction to his code. Commented Nov 28, 2012 at 2:59

2 Answers 2

17
int f(int a[], int n)
{
    if (n == 1)
        return a[0];
    n--;
    return f(a + (a[0] > a[n]), n);
}
Sign up to request clarification or add additional context in comments.

9 Comments

it moves the starting point of the array up by one in the recursed call if a[0] in the current stack frame is larger than a[n]. Its also quite ingenious. I wish I could up-vote it more than once.
@JosuéMolina This is C, there is no boolean: the result of a[0] > a[n] is either 0 or 1. It is like (a[0] > a[n]) ? (a + 1) : a
@JosuéMolina It's pointer arithmetic. By adding 1 to the pointer, the recursive step will get the next spot in the array. That is, if the current value (a[0]) is greater than the last value, then the current value can't be the smallest element, so might as well try the next one. Otherwise, we stay with the current value until we've "shrunk" the array (n--). What we're left with is the smallest value.
The only way this pukes is if the grader passes in a value < 1 for the size (no specification on zero-length arrays was given in the question, however. but it is the only chance of being marked down for what is otherwise a beatiful answer).
Exactly. what do you return on n<1 ? you can't deref the array obviously. throw an exception?? =P. Chalk it up to an instructor that didn't define the problem with all boundaries accounted. None-the-less, your solution is outstanding. Love an elegant recursion solution.
|
2

kmkaplan's solution is awesome, and I upvoted him. This would have been my not as awesome solution:

int f(int a[], int n)
{
    if(n == 1)
        return a[0];

    n--;

    if(a[0] > a[n])
        a[0] = a[n];

    return f(a, n);
}

The smallest element of the array, at any given time, is stored in a[0]. I originally included a non-modifying version, but then it occurred to me that it was not tail-recursive.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.