【问题标题】:OutOfMemoryError creating a tree recursively?OutOfMemoryError 递归创建树?
【发布时间】:2013-11-04 12:19:15
【问题描述】:
 root = new TreeNode(N);
 constructTree(N, root);

 private void constructTree(int N, TreeNode node) {
    if (N > 0) {
        node.setLeft(new TreeNode(N-1));
        constructTree(N-1, node.getLeft());
    }
    if (N > 1) {
        node.setMiddle(new TreeNode(N-2));
        constructTree(N-2, node.getMiddle());
    }
    if (N > 2) {
        node.setRight(new TreeNode(N-3));
        constructTree(N-3, node.getRight());
    }

假设N为根号,三者会创建一个左中右节点N-1、N-2、N-3。

前:

     5
   / | \
  4  3  2
 /|\
3 2 1

等等

我的 TreeNode 类有以下变量:

private int number;
private TreeNode left, middle, right;

每当我构造一个整数大于 28 的树时,我都会收到 OutOfMemoryError。我的递归方法是非常低效还是很自然?谢谢!

【问题讨论】:

  • 当 N 为 29 时,生成的树应该有 1680 万个节点。由于您还没有向我们展示TreeNode,我不知道每个节点有多少字节;但我真的看不出它会给你带来问题。你的堆大小设置为多少?

标签: java recursion tree


【解决方案1】:

理论上,深度为 N 的完整三叉树将具有 (3^(N+1) - 1) / 2 节点。如果 N 为 28,则为 34,315,188,682,441 个节点。如果每个节点以某种方式只占用 1 个字节,那仍然是 31.2 TB 的 RAM。在那之前你的内存会用完。

编辑:但是,您的代码似乎没有生成完整的树。当我运行以下程序来计算新节点的数量时:

static long nodes = 0;

static void constructTree(int N) {
   if (N > 0) {
       ++nodes;
       constructTree(N-1);
   }
   if (N > 1) {
       ++nodes;
       constructTree(N-2);
   }
   if (N > 2) {
       ++nodes;
       constructTree(N-3);
   }
}

public static final void main (String[] args) throws Exception {
    nodes = 1;
    constructTree(28);
    System.out.println(nodes);
}

假设您的 TreeNode 构造函数不创建新节点,则表明您在 N=28 处创建了 34,850,335 个新节点,在 N=29 处创建了 64,099,760 个新节点。鉴于您暗示 N=28 成功,这更有意义。由于您没有显示您的TreeNode,因此我们无法准确判断它将使用多少内存,但这些数字与典型的 JVM 内存限制在同一数量级内。您可以稍微增加最大 JVM 内存以挤出一两个更多级别。

但是,您可能希望准确地思考为什么要生成这棵树,并尝试提出一种不同的算法来完成您正在做的事情。

【讨论】:

  • 这是一个家庭作业。基本上它指定我们在给定根号时创建整个树。我阅读了一位 TA 的评论,其中指出“不应该有内存错误”。但我认为该声明与他们的测试标准有关,而不是我们的程序本身。当时我并没有意识到这一点,并开始认为他的意思是程序不应该有任何内存错误。然而,您的描述帮助我更好地理解,因为我没有完全意识到我的代码实际上创建了一个不相等的树(尽管这是我计划的)。太感谢了!对每个人来说
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-02
  • 2011-05-08
  • 2015-03-18
  • 2017-09-21
  • 2012-08-23
相关资源
最近更新 更多