简体   繁体   中英

How to handle deep recursion when working with ArrayLists?

So earlier today I ran into an issue and now it's evening-time and all I've successfully done is identify the source of the issue.

在此输入图像描述

I have a bunch of nodes that make up a figure. These nodes can also have node-children of their own (think shoulder->elbow->hand). A possible scenario for this figure is that one of these nodes may have attached to it many, many generations of descendant nodes (as pictured).

The problem I'm having is if I run a typical recursive function like updatePosition() when the root node is moved, this function iterates down its line of children and eventually I get a StackOverflowError.

The problem I have is I don't know how to get around this limitation. I understand I have to abandon this recursive method, but, how? I'd really appreciate some input/advice to point me in the right direction.

Also note, this issue is occurring on Android devices, I'm assuming this leaves me with a relatively lower Stack limit than on a typical desktop JVM.


Edit: According to dangVarmit solution of using a manually-created Stack, here's what I've come up with. I haven't been able to test this code yet, but it seems like it would work.

OLD CODE

void validatePosition()
{
    if (_positionIsDirty == true)
        updatePosition();
}

void updatePosition()
{
    _positionIsDirty = false;
    // etc...

    for (int i = _childrenNodes.size() - 1; i >= 0; --i)    // This recursive part caused the StackOverflowError
        _childrenNodes.get(i).updatePosition();
}

NEW CODE

void validatePosition()
{
    if (_positionIsDirty == true)
    {
        // Create a Stack and add this Node to it.
        Stack stack = new Stack();
        stack.push(this);

        while (stack.empty() == false)
        {
            // Pop top-most Node in Stack.
            Node node = stack.pop();

            // Update it and push its children onto the Stack.
            node.updatePosition();
            for (int i = node._childrenNodes.size() - 1; i >= 0; --i)
                stack.push(node._childrenNodes[i]);

        }
    }
}

void updatePosition()
{
    _positionIsDirty = false;
    // etc...
}

Create a stack or ArrayList of nodes. push the root object onto the stack and then start a while loop (for stack not empty)

the body of the loop operates on the top node of the stack. At any point where you would have recursed into the function you will now push the new node onto the stack and then use continue to begin the loop over on the new top level node.

When the recursive function is done with a certain node it pops the node off the stack and calls continue to begin the loop over.

Your loop needs to account for the fact that it may be called several times on the same node so you want to manage the state a little more. In a recursive function you would return to the parent caller in the same place in the function with the same state (local variables, etc) You lose that so you have to manage that state your self. In a left, right child node, you would need to remember that you checked and processed the left node so you can skip that on the second pass and check/process the right node this time (or pop the stack and continue if you've done both nodes)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM