繁体   English   中英

使用ArrayLists时如何处理深度递归?

[英]How to handle deep recursion when working with ArrayLists?

所以今天早些时候我遇到了一个问题,现在是晚上时间,我所做的一切都是确定问题的根源。

在此输入图像描述

我有一堆构成数字的节点。 这些节点也可以有自己的节点子节点(想想肩 - >肘 - >手)。 这个图的一个可能的情况是这些节点中的一个可能已经连接了许多代子节点(如图所示)。

我遇到的问题是,如果我在移动根节点时运行像updatePosition()这样的典型递归函数,这个函数会迭代它的子行,最终得到一个StackOverflowError。

我遇到的问题是我不知道如何解决这个限制。 我明白我必须放弃这种递归方法,但是,怎么样? 我真的很感激一些意见和建议,指出我正确的方向。

另请注意,此问题发生在Android设备上,我假设这使我的堆栈限制相对低于典型的桌面JVM。


编辑:根据使用手动创建的堆栈的dangVarmit解决方案,这是我想出的。 我还没有能够测试这段代码,但似乎它会起作用。

旧代码

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();
}

新代码

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...
}

创建节点的堆栈或ArrayList。 将根对象推入堆栈然后启动while循环(堆栈不为空)

循环体在堆栈的顶部节点上运行。 在您已经递归到函数的任何时候,您现在将新节点推送到堆栈,然后使用continue在新的顶级节点上开始循环。

当递归函数与某个节点完成时,它会将该节点从堆栈中弹出并继续调用以开始循环。

您的循环需要考虑到它可能在同一节点上多次调用的事实,因此您希望稍微管理一下状态。 在递归函数中,您将返回到具有相同状态(局部变量等)的函数中相同位置的父调用者。您将失去该函数,因此您必须自己管理该状态。 在左右子节点中,您需要记住您已检查并处理了左侧节点,因此您可以在第二次传递时跳过该节点并在此次检查/处理正确的节点(或弹出堆栈并继续,如果您已经完成两个节点)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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