Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法在Java中向二进制搜索树添加1000000个元素_Java_Algorithm_Binary Tree_Binary Search Tree - Fatal编程技术网

无法在Java中向二进制搜索树添加1000000个元素

无法在Java中向二进制搜索树添加1000000个元素,java,algorithm,binary-tree,binary-search-tree,Java,Algorithm,Binary Tree,Binary Search Tree,我正在做一个二叉搜索树作为作业。 我在尝试添加1000000个元素时遇到问题。 我在插入15000个元素后出错:线程主java.lang.StackOverflowerError中出现异常 我的代码有问题,我找不到哪里做错了 public class BinarytreeInsert { public static void main(String[] args) { new BinarytreeInsert().run(); } static cla

我正在做一个二叉搜索树作为作业。 我在尝试添加1000000个元素时遇到问题。 我在插入15000个元素后出错:线程主java.lang.StackOverflowerError中出现异常 我的代码有问题,我找不到哪里做错了

public class BinarytreeInsert {

    public static void main(String[] args) {
        new BinarytreeInsert().run();
    }

    static class Node {

        Node left;
        Node right;
        int value;

        public Node(int value) {
            this.value = value;
        }
    }

    public void run() {
        Node rootnode = new Node(25);
        System.out.println("Building tree with root value " + rootnode.value);
        System.out.println("=================================");
        for(int i = 0 ; i<1_000_000;i++)
            insert(rootnode, i);

    }


    public void insert(Node node, int value) {
        if (value < node.value) {
            if (node.left != null) {
                insert(node.left, value);
            } else {
                System.out.println("  Inserted " + value + " to left of Node " + node.value);
                node.left = new Node(value);
            }
        } else if (value > node.value) {
            if (node.right != null) {
                insert(node.right, value);
            } else {
                System.out.println("  Inserted " + value + " to right of Node " + node.value);
                node.right = new Node(value);
            }
        }
    }
}

正如@ajp15243提到的,问题的直接原因是您有一个递归插入方法,该方法递归太深。这将填充线程的方法调用堆栈,并触发异常

根本问题是算法中的设计缺陷,再加上病理测试数据

问题是您的insert方法没有尝试创建平衡的二叉树。也就是说,它不会尝试创建一棵树,其中节点的左子树的节点数与右子树的节点数大致相同

病理学是,您的算法与测试数据相结合,生成一个树,其中每个节点的左子节点都为null。或者类似的。。。。最终的结果是您的树极不平衡,您必须非常深入地递归才能找到插入点

有几种方法可以解决这个问题:

理想的方法是使用一种算法来重新实现树,该算法保持树的平衡,与插入元素的顺序无关

作弊的方法是找出一个插入顺序,这将导致一个平衡的树。。。使用当前的算法

最后,您可以创建一个元素数组,洗牌数组,然后按洗牌顺序插入元素。这可能会导致一棵树不完全平衡,但病态行为发生的可能性将非常小


正如@ajp15243提到的,问题的直接原因是您有一个递归插入方法,该方法递归太深。这将填充线程的方法调用堆栈,并触发异常

根本问题是算法中的设计缺陷,再加上病理测试数据

问题是您的insert方法没有尝试创建平衡的二叉树。也就是说,它不会尝试创建一棵树,其中节点的左子树的节点数与右子树的节点数大致相同

病理学是,您的算法与测试数据相结合,生成一个树,其中每个节点的左子节点都为null。或者类似的。。。。最终的结果是您的树极不平衡,您必须非常深入地递归才能找到插入点

有几种方法可以解决这个问题:

理想的方法是使用一种算法来重新实现树,该算法保持树的平衡,与插入元素的顺序无关

作弊的方法是找出一个插入顺序,这将导致一个平衡的树。。。使用当前的算法

最后,您可以创建一个元素数组,洗牌数组,然后按洗牌顺序插入元素。这可能会导致一棵树不完全平衡,但病态行为发生的可能性将非常小

问题是你的插入函数——因为你的树很深,你递归得太深了。没有编译器选项的Java不支持特别深的递归调用

最好的解决方案是将递归插入函数转换为迭代函数。简言之,只需将函数中的代码固定在循环中,在每次迭代中更改节点即可

此外,我建议a,例如a

请注意,您的树当前的外观如下:

   25
  /  \ 
0     26
 \     \
  1     27
   \     \
    2     28
     \     ...
      3
       ...
这将比它需要的要深得多,实际上,它将在高度上,这将反过来导致在树上的操作

使用自平衡树,高度永远不会超过Olog n。

问题在于插入函数-因为树很深,所以递归太深。没有编译器选项的Java不支持特别深的递归调用

最好的解决方案是将递归插入函数转换为迭代函数。简言之,只需将函数中的代码固定在循环中,在每次迭代中更改节点即可

此外,我建议a,例如a

请注意,您的树当前的外观如下:

   25
  /  \ 
0     26
 \     \
  1     27
   \     \
    2     28
     \     ...
      3
       ...
这将比它需要的要深得多,实际上,它将在高度上,这将反过来导致在树上的操作


使用自平衡树,高度永远不会超过Olog n。

插入方法是递归的。任何方法调用都会将有关该方法调用实例的信息放在调用堆栈上,并从方法返回将其删除。此堆栈的内存空间有限。如果您通常在递归过程中一次调用过多的方法,那么堆栈会变得太大—它会溢出—程序会终止
ee看起来像是以递增顺序重复添加元素……您可以看看如何实现交互式插入算法。正如其他人所暗示的,问题是,当您以递增顺序插入时,二叉树变成了一个线性列表。所以你的递归有15000层深。理想情况下,你需要一些方法来平衡你的树。或者您需要一个迭代插入算法。您的插入方法是递归的。任何方法调用都会将有关该方法调用实例的信息放在调用堆栈上,并从方法返回将其删除。此堆栈的内存空间有限。如果你通常在递归过程中一次调用太多方法,那么堆栈会变得太大——它会溢出——程序会终止。你应该考虑当你以递增的顺序重复添加元素时,你的树会是什么样子……你可以看看如何实现交互式插入算法。问题是,正如其他人所暗示的,当您按递增顺序插入时,二叉树将变成一个线性列表。所以你的递归有15000层深。理想情况下,你需要一些方法来平衡你的树。或者你需要一个迭代插入算法。建议阅读,如果你不知道什么O。。。意思是-。事实上,高度不仅仅是对数N。它应该非常接近对数N。。。没有标度常数。说一个数字接近O。。。是数学上的胡说八道,因为。。。是限制的简写符号,不是数字。如果你不知道什么是限制,建议阅读。。。意思是-。事实上,高度不仅仅是对数N。它应该非常接近对数N。。。没有标度常数。说一个数字接近O。。。是数学上的胡说八道,因为。。。是极限的简写符号,而不是数字。处理它的第四种方法是将插入法改为迭代法。只要不考虑运行时,就可以解决堆栈溢出问题。第五种方法,也是真正的欺骗方法,是增加堆栈大小。@gms7777-注意。然而,在这两种情况下都有重要的注意事项。第四种处理方法是将插入法改为迭代法。只要不考虑运行时,就可以解决堆栈溢出问题。第五种方法,也是真正的欺骗方法,是增加堆栈大小。@gms7777-注意。然而,在这两种情况下都有重要的注意事项。