当前位置: 首页 > 知识库问答 >
问题:

OutOfMemory递归创建树时出错?

公冶弘壮
2023-03-14
 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的左中右节点。

EX:

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

等。

我的 TreeNode 类具有以下变量:

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

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

共有1个答案

卫焕
2023-03-14

理论上,深度为N的全三元树将具有(3^(N1)-1)/2节点。如果N为28,则为34315188682441个节点。如果每个节点以某种方式只占用了1个字节,那么仍有31.2TB的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);
}

假设您的< code>TreeNode构造函数没有创建新节点,它显示您在N=28时创建了34,850,335个新节点,在N=29时创建了64,099,760个新节点。鉴于你暗示N=28成功,这更有意义。因为您没有显示您的< code>TreeNode,所以我们不能确切地说出它将使用多少内存,但是这些数字与典型的JVM内存限制在同一数量级。您可以稍微增加您的最大JVM内存来挤出一两个级别。

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

 类似资料:
  • 我有一个父子关系数据库。数据如下所示,但可以以任何方式呈现(字典、列表列表、JSON等)。 我需要的输出是一个层次化的JSON树,它将用d3呈现。数据中有离散的子树,我将附加到根节点。所以我需要递归地遍历链接,并建立树结构。我最多只能遍历所有人并附加他们的孩子,但我不知道如何进行高阶链接(例如,如何将有孩子的人附加到其他人的孩子)。这类似于这里的另一个问题,但我无法提前知道根节点,因此无法实现公认

  • 问题内容: 我有一个像这样设置的物料清单表: item-parent 显示物料清单的最终结果是这样显示的: 最终结果也可能是多级的,如下所示: 它可以无限进行: 现在,我要么只是从数据库中获得1级: 或从表中拉出每一行,并使用递归函数仅对所需行进行排序,但这显然效率不高,因为我可能只需要10行,但我拉出10,000条记录。递归函数的输出将只创建一个像这样的树: 我所知道的是,我从项目1开始。项目5

  • 问题内容: 我使用ostermillerutils库创建base64字符串,但是如果图像很重,则会出现OutOfMemory错误。如果我尝试转换的图像是简单图像,则代码工作正常。 我也尝试这样做,但是当我尝试对它进行解码时,base64是不正确的。 请为JDK 1.4和更高版本的Java建议解决方案。 问题答案: 我通过使用javabase64-1.3.1.jar库解决了我的问题。 我首先将bas

  • 问题内容: 我有一个Person类,我想创建一棵树。这是Person类的解释器。 c1是左边的孩子,c2是右边的孩子。所以说我创建了三个这样的人: 因此,在这里您说亚当是根节点,亚当的左孩子是b,这是芭芭拉,他的右c是卡尔,依此类推。 所以我想做的是编写一个count方法,该方法计算包括在内的子代数。因此a.count()将返回6(如果Person f没有任何孩子)。 这是我的代码: 我在纸上运行

  • 为了更灵活地编写代码,我每天都在尝试做不同的问题,但这一次却让我停滞不前。 下面的代码应该是在预序遍历中从给定的字符串建立一个二叉树。即“5 3 1 N N N 7 N N”表示下面的二叉树。元素之间用空格分隔,N标记空节点,空节点正好为NULL。 它应该像遍历拆分的字符串一样简单,当找到以外的东西时,就用该值构造一个,并增加。 增加之后,我再次将下一个数组元素放入左侧子树中。如果遇到,则不需要执

  • 问题内容: 我有一个将位置链接在一起的数据库表;一个位置可以在一个位置,也可以在另一个位置内。 这是深入探讨MySQL / PHP的深度: 在给定父级位置的情况下,如何使用MySQL如何获得其所有后代位置,无论深度如何? 问题答案: mysql.com上有 一篇漂亮的文章 ,概述了管理分层数据的各种方法。我认为它为您的问题提供了完整的解决方案,并显示了各种不太简单但较快的方法(例如嵌套集)。