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错误。我该如何防止这种情况发生?
答案 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。