【问题标题】:StackOverFlow Error when converting 1,000,000 Nodes in a Splay Tree to a SinglyLinkedList将 Splay 树中的 1,000,000 个节点转换为 SinglyLinkedList 时出现 StackOverFlow 错误
【发布时间】:2017-10-11 08:16:17
【问题描述】:

我已经实现了一个使用节点存储数据的 Splay Tree 类。在这个类中,我尝试将节点的数据转换为单链表。可以将 1,000,000 个节点插入到展开树中,并且可以完美运行。当树包含 1,000,000 个节点时,使用递归我得到一个 StackOverFlow 错误。但是,当树包含大约 15000 个节点时,它可以毫无问题地转换为链表。

这是我的 toList 方法的代码,它位于 splay 树类中

public LinkedList<Node> toList() {

   LinkedList<Node> list = new LinkedList<Node>();
   Node node = root;
   addToList(node, list);

   return list;
}

private void addToList(Node node, LinkedList<Node> list) {
   if(node != null) {
      addToList(node.left, list);
      list.add(node);
      addToList(node.right, list);
   }
}

我用下面这个测试类来测试这个方法的功能

@Test
public void testConversionToLinkedList {
   SplayTree<Integer,String> st = new SplayTree<Integer,String>();
   for(int i = 0; i < 1000000; i++) {
      st.insert(i, Integer.toString(i));
   }
   assertEquals(1000000, st.size());

   LinkedList<Node> list = st.toList();
   assertEquals(1000000, list.size());
}

当输入的大小约为 15000 时测试通过,但是任何大于该大小的数字都会显示 StackOverFlowError

错误发生在addToList(node.left, list);这一行

这真的很奇怪,因为当我使用相同的递归技术将节点的数据打印到 txt 文件时,没有 StackOverFlow 错误并且数据打印完美。

我尝试使用 In Order Traversal、PreOrder 和 PostOrder,但在 1,000,000 个节点上仍然收到相同的错误。我确实知道它可能进行的递归太深并且堆栈内存不足。如果是这种情况,有什么方法可以将节点的展开树转换为链表? 知道可能出了什么问题吗?干杯

【问题讨论】:

    标签: java recursion tree stack-overflow


    【解决方案1】:

    你的问题是递归算法。正如您发现的那样,堆栈大小是有限制的,这是在您进行递归时构建的。

    您始终可以将递归转换为循环。

    这里有一些使用循环的 DFS 和 BFS 算法示例:Non recursive Depth first search algorithm

    【讨论】:

      【解决方案2】:

      您可以增加堆栈的大小。为此,您必须将参数传递给 jvm。 格式为 -Xss[g|G|m|M|k|K]。 例如:java -Xss4m YourTreeProgram

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-08
        • 1970-01-01
        相关资源
        最近更新 更多