Can't Add 1,000,000 Elements to Binary Search Tree in Java

爱⌒轻易说出口 提交于 2019-12-08 07:09:15

问题


I am making an Binary Search Tree as an assignment.
I am having problem when i try to add 1,000,000 elements.
I'm getting error after 15,000 elements inserted:

Exception in thread "main" java.lang.StackOverflowError

Something wrong with my code i could not find where i did wrong.

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

回答1:


As @ajp15243 mentions, the immediate cause of the problem is that you have a recursive insert method that is recursing too deeply. This fills the thread's method call stack, and triggers the exception.

The root problem is a design flaw in your algorithm, combined with "pathological" test data.

The problem is that your insert method does not attempt to create a balanced binary tree. That is, it does not attempt to create a tree where the left subtree of an node has (roughly) the same number of nodes as the right subtree.

The pathology is that the your algorithm combined with the test data results in a tree where the left child of every node is null. (Or something like that ...). The end result is that your tree is extremely unbalanced, and you have to recurse very deeply to find the insertion point.


There are a couple of ways to deal with this:

  • The ideal way would be to reimplement your tree using an algorithm that keeps the tree balanced, independent of the order in which elements are inserted.

  • The "cheat" way would be to figure out an insertion order that is going to result in a balanced tree ... with the current algorithm.

  • Finally, you could create an array of elements, shuffle the array and then insert the elements in shuffled order. That might result in a tree that is not perfectly balanced, but the chances of pathological behaviour will be vanishingly small.




回答2:


The problem is your insert function - since your tree is very deep, you recurse too deep. And Java, without compiler options, doesn't support particularly deep recursive calls.

The best solution would be to convert your recursive insert function to iterative. In short - just stick the code in your function in a loop, changing node at every iteration.

Additionally, I'd advise a self-balancing tree, such as a red-black tree.

Note that your tree will currently look something like this:

   25
  /  \ 
0     26
 \     \
  1     27
   \     \
    2     28
     \     ...
      3
       ...

This will be much deeper than it needs to be (indeed it will be O(n) height, which will, in turn, lead to O(n) operations on the tree).

With a self-balancing tree, the height will never be more than O(log n).



来源:https://stackoverflow.com/questions/21139851/cant-add-1-000-000-elements-to-binary-search-tree-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!