2

One of Codility tasks is to find the height of a binary tree. The task guarantees that the height won't exceed 500. So the easiest solution that comes to mind is to just use recursion.

Now, while such a solution passes all the tests in Codility I wonder if I can safely assume 500 is not too much (for any computer/test platform that's likely to be Codility's test platform) or whether I should avoid recursion and either simulate it or find the height of the tree some other way?

Edit: As PM 77-1 pointed out, the answer might depend on what my recursion looks like. So I've included it. There's a struct defined:

struct tree {
  int x;
  tree * l;
  tree * r;
}; 

And here is my solution:

int getHeight(tree const * T, int height)
{
    int maxHeight = height;
    if (T->l)
    {
        maxHeight = getHeight(T->l, height + 1);
    }
    if (T->r)
    {
        maxHeight = max(maxHeight, getHeight(T->r, height + 1));
    }
    return maxHeight;
}

int solution(tree * T)
{
    return getHeight(T, 0);
}

Now my question is - knowing how my solution looks like (how much memory it can use/etc...) and NOT knowing what the test platform specs are can I safely assume 500 recursive calls won't cause a stack overflow or not? (Because if it were 50 or 5 I think I could safely assume that no matter the test platform.)

Edit: I deliberately haven't specified the language as Codility supports a multitude of them and I'd like to get an answer concerning more than one, if possible. However, I was using C++ in my solution so I guess that's the language I'm most interested in.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
NPS
  • 6,003
  • 11
  • 53
  • 90
  • 1
    Your question is too general. Not all recursions made equal. If, for example, your recursion creates a really large object on every call, you may get `out of memory` much earlier than `stack overflow`. – PM 77-1 Oct 08 '14 at 00:05
  • 1
    No one can say it isn't too much for any computer/test platform. It may be to too much for very old computers or embedded systems, but any modern platform should handle it without a problem - also read this: http://stackoverflow.com/questions/1006867/retrieving-a-binary-tree-nodes-depth-non-recursively – Kevin Oct 08 '14 at 00:18
  • 1
    The short answer is **NO**, you cannot make such assumption. *Any platform* is a huge requirement. Think of embedded Java with minimal memory on a intelligent coffee maker. – PM 77-1 Oct 08 '14 at 00:20
  • Of course, you're right, "any platform" is too broad. But I had in mind rather "any platform that's likely to be Codility's test platform". – NPS Oct 08 '14 at 00:22

1 Answers1

3

This depends on a number of factors, including language and the amount of stack space your method uses for each call.

For Java, reference types are 8 bytes and the default stack size is usually 512 kB. A method has at the bare minimum 1 reference (8 bytes) needed to store the return address, plus whatever variables and parameters you've declared (likely to also be 8 bytes each, since most variables in Java you'll use will be either references or 8 byte ints).

Lets calculate how much stack space is available for each call. Note that this calculation is neglecting the space required by the rest of your program, and assuming the recursive method is the only method in the stack. We'll also assume that the method is not calling methods other than itself, since it can be hard to say how much stack they'll need. In reality, you'll have somewhat less space to work with.

(512000 bytes) / (500 calls) = 1024 bytes per call
(1024 bytes per call) / (8 bytes per reference) = 128 references per call

So for 500 levels of recursion, you'd be able to have 127 variables and parameters in your method before you run out of stack space (since we have subtracted 1 for the return address). Even with the assumptions, it seems unlikely that you'll hit this limit.

user2503846
  • 924
  • 1
  • 7
  • 10
  • That's exactly the kind of answer I was looking for! However, before accepting I'll wait to see if others can provide some info on other programming languages. Or maybe you can? – NPS Oct 08 '14 at 00:17
  • 2
    Some languages will have optimizations to reduce the stack usage for recursive method calls. You won't find a language that consumes much more stack than Java for each method call, since this is almost universal behavior. Stack size and reference size will also vary. For instance, if you've got a 32 bit operating system, some languages, like C (but not Java, since it uses a virtual machine) will have 32 bit (4 byte) references. In this case you'd be able to store more references on the same amount of stack space. There is no guarantee in any case what the exact stack space will be. – user2503846 Oct 08 '14 at 00:25