将元素添加到BST java时的StackOverflow

时间:2015-03-11 20:11:46

标签: java stack-overflow binary-search-tree

private Node put(Node x, Float longitude, Float latitude, String place, String address) {
    if (x == null)
        return new Node(longitude, latitude, place, address, 1);
    int cmpX = longitude.compareTo(x.longitude);
    int cmpY = latitude.compareTo(x.latitude);
    if (cmpX < 0 | (cmpX == 0 && cmpY < 0)) {
        if (x.left == null) { x.left = new Node(longitude, latitude, place, address, x.N);}
        else{x.left = put(x.left, longitude, latitude, place, address);}
    } else if (cmpX >= 0) {
        if (x.right == null) {  x.right = new Node(longitude, latitude, place, address, x.N);}
        else{x.right = put(x.right, longitude, latitude, place, address);}
    }
    x.N = 1 + size(x.left) + size(x.right);
    return x;
}

我有这个代码,我尝试使用它插入BST,它适用于前3000个左右的元素,然后导致StackOverFlow错误。我该如何防止这种情况发生?

1 个答案:

答案 0 :(得分:0)

您遇到StackOverflowError的原因是您按照已排序的顺序插入了商品。让我们看看在这种情况下会发生什么。我会使用整数,即使你有更复杂的对象,为了简单看看会发生什么。

插入1:

Root(1)

插入2后:

Root(1)
    \
     (2)

插入3后:

Root(1)
    \
     (2)
      \
       (3)

插入n:

Root(1)
    \
     (2)
      \
       ...
        \
         (n)

您将put实现为递归方法。因此,当你添加了3000个元素,并且你试图添加第3001个元素时,你需要重复3000次,现在调用堆栈上有3000个put个副本,关于你说的位置它溢出了。

您可以使用put循环而不是递归将while转换为迭代方法。这将消除StackOverflowError,但它不会解决问题的根(可以这么说) - 你的BST看起来像一个链表。

您可以按随机顺序提交元素。它可能看起来像这样:

    Root(1123)
     /        \
   (799)       (2800)
   /  \       /     \
 (64) (999) (1599)   (2901)

它可能没有得到适当的平衡,但很可能它不会转换为按排序顺序插入的链表情况。

当一个分支与另一个分支相比太大时,您可以对特定节点执行轮换。如果你喜欢冒险,你可以实现一个red-black tree,一个使用旋转来保持树平衡“足够”的BST。