Java-堆栈溢出错误
我需要一些帮助 首先我有一个BinarySearchTree类Java-堆栈溢出错误,java,stack-overflow,Java,Stack Overflow,我需要一些帮助 首先我有一个BinarySearchTree类 import java.util.ArrayList; import java.util.List; public class BinarySearchTree<E extends Comparable<? super E>> { private BSTNode<E> root; private int size; // root ==null iff size == 0 public B
import java.util.ArrayList;
import java.util.List;
public class BinarySearchTree<E extends Comparable<? super E>> {
private BSTNode<E> root;
private int size;
// root ==null iff size == 0
public BinarySearchTree() {
root = null;
size = 0;
}
public boolean add(E value) {
int oldSize = size;
root = addHelper(root, value);
return oldSize != size;
}
private BSTNode<E> addHelper(BSTNode<E> n, E val) {
if (n == null) {
n = new BSTNode<E>(null, val, null);
size++;
} else {
int diff = val.compareTo(n.getData());
if (diff < 0)
n.setLeft(addHelper(n.getLeft(), val));
else if (diff > 0)
n.setRight(addHelper(n.getRight(), val));
}
return n;
}
public boolean remove(E value) {
int oldSize = size;
root = removeHelp(root, value);
return oldSize != size;
}
// helper method for remove
private BSTNode<E> removeHelp(BSTNode<E> n, E val) {
if (n != null) {
int diff = val.compareTo(n.getData());
if (diff < 0)
n.setLeft(removeHelp(n.getLeft(), val)); // traverse the left
// side
else if (diff > 0)
n.setRight(removeHelp(n.getRight(), val)); // traverse right
// side
else // if value is found
{
size--;
if (n.getLeft() == null && n.getRight() == null) // if value
// contained in
// leaf, just
// make nul;
n = null;
else if (n.getRight() == null) // single child to left
n = n.getLeft(); // move the child up to replace removed
// node
else if (n.getLeft() == null)
n = n.getRight();
else // two children, replace value with max of left subtree -
// it will not have a right subtree
{
n.setData(getMax(n.getLeft()));
// now remove max of left subtree from its previous position
n.setLeft(removeHelp(n.getLeft(), n.getData()));
// add 1 back to size since size will be decremented from
// this 2nd removal
size++;
}
}
}
return n;
}
// helper method to find Max of a subtree
private E getMax(BSTNode<E> n) {
while (n.getRight() != null)
n = n.getRight();
return n.getData();
}
public boolean isPresent(E value) {
assert value != null : "Precondition failed: value != null";
if (root == null)
return false;
return isPresentHelp(root, value);
}
public boolean isPresentHelp(BSTNode<E> n, E item) {
if (n == null)
return false;
else {
E temp = n.getData();
// if item to search is greater than node, traverse right
if (temp.compareTo(item) < 0)
return isPresentHelp(n.getRight(), item);
else if (temp.compareTo(item) > 0)
return isPresentHelp(n.getLeft(), item);
else
return true;
}
}
public int size() {
return size;
}
public int height() {
return heightHelper(root);
}
public int heightHelper(BSTNode<E> n) {
int tempLeft, tempRight;
if(n == null)
return -1;
tempLeft = 1 + heightHelper(n.getLeft());
tempRight = 1 + heightHelper(n.getRight());
if(tempLeft > tempRight)
return tempLeft;
else
return tempRight;
}
public List<E> getAll() {
List<E> result = new ArrayList<E>();
return getAllHelp(root, result);
}
public List<E> getAllHelp(BSTNode<E> n, List<E> result) {
if (n != null) {
// traverse left to lowest value
getAllHelp(n.getLeft(), result);
// add to arraylist if it can go left no further (smallest current
// value)
result.add(n.getData());
// traverse right if can't go left anymore
getAllHelp(n.getRight(), result);
}
return result;
}
public E max() {
return getMax(root);
}
public E min() {
return getMin(root);
}
private E getMin(BSTNode<E> n) {
while (n.getLeft() != null)
n = n.getLeft();
return n.getData();
}
public boolean iterativeAdd(E data) {
BSTNode<E> n = root;
while (n != null) {
if (n.getData().compareTo(data) > 0) {
if (n.getLeft() == null) {
n.setLeft(new BSTNode<E>(data));
size++;
return true;
} else
n = n.getLeft();
} else if (n.getData().compareTo(data) < 0) {
if (n.getRight() == null) {
n.setRight(new BSTNode<E>(data));
size++;
return true;
} else
n = n.getRight();
} else
return false;
}
root = new BSTNode<E>(null, data, null);
size++;
return true;
}
public E get(int kth) {
assert 0 <= kth && kth < size() : "Precondition failed: 0 <= kth < size()";
// keep track of which index recursive call is on (or the kth element)
int count[] = { 0 };
return getHelp(kth, root, count);
}
public E getHelp(int nth, BSTNode<E> n, int[] count) {
E result = null;
if (n != null) {
result = getHelp(nth, n.getLeft(), count);
if (result == null) {
if (count[0] == nth) {
return n.getData();
} else {
count[0]++;
result = getHelp(nth, n.getRight(), count);
}
}
}
return result;
}
public List<E> getAllLessThan(E value) {
List<E> result = new ArrayList<E>();
return getAllLessHelp(root, result, value);
}
public List<E> getAllLessHelp(BSTNode<E> n, List<E> result, E value) {
if (n != null) {
getAllLessHelp(n.getLeft(), result, value);
if (n.getData().compareTo(value) < 0) {
result.add(n.getData());
}
getAllLessHelp(n.getRight(), result, value);
}
return result;
}
public List<E> getAllGreaterThan(E value) {
List<E> result = new ArrayList<E>();
return getAllGreaterHelp(root, result, value);
}
// returns the BSTNode containing the value
public List<E> getAllGreaterHelp(BSTNode<E> n, List<E> result, E value) {
if (n != null) {
if (n.getData().compareTo(value) > 0) {
getAllGreaterHelp(n.getLeft(), result, value);
result.add(n.getData());
}
getAllGreaterHelp(n.getRight(), result, value);
}
return result;
}
public int numNodesAtDepth(int d) {
return numNodesHelp(d, root, 0);
}
public int numNodesHelp(int d, BSTNode<E> n, int count) {
count = 0;
if (n != null) {
if (d == 0)
count++;
else {
count += numNodesHelp(d - 1, n.getLeft(), count);
count += numNodesHelp(d - 1, n.getRight(), count);
}
}
return count;
}
public void printTree() {
printTree(root, "");
}
private void printTree(BSTNode<E> n, String spaces) {
if (n != null) {
printTree(n.getRight(), spaces + " ");
System.out.println(spaces + n.getData());
printTree(n.getLeft(), spaces + " ");
}
}
private static class BSTNode<E extends Comparable<? super E>> {
private E data;
private BSTNode<E> left;
private BSTNode<E> right;
public BSTNode() {
this(null);
}
public BSTNode(E initValue) {
this(null, initValue, null);
}
public BSTNode(BSTNode<E> initLeft, E initValue, BSTNode<E> initRight) {
data = initValue;
left = initLeft;
right = initRight;
}
public E getData() {
return data;
}
public BSTNode<E> getLeft() {
return left;
}
public BSTNode<E> getRight() {
return right;
}
public void setData(E theNewValue) {
data = theNewValue;
}
public void setLeft(BSTNode<E> theNewLeft) {
left = theNewLeft;
}
public void setRight(BSTNode<E> theNewRight) {
right = theNewRight;
}
}
}
嗯。谢谢大家的帮助。我真的很感激。你们回答得太快了:)Java中堆栈的最大深度取决于分配的内存量,它表示 在这里,通过更大的测试,递归函数的深度已经达到极限。还提到32000是一个神奇的数字——不管怎样,您可以通过为堆栈分配更多内存来解决这个问题。如果希望能够处理10240000层的最坏情况,您可能需要分配很多 在
iterativeAdd
案例中出现错误的原因是,您正在反向添加元素:
if (n.getData().compareTo(data) > 0) {
if (n.getLeft() == null) {
n.setLeft(new BSTNode<E>(data));
size++;
return true;
if(n.getData().compareTo(data)>0){
如果(n.getLeft()==null){
n、 setLeft(新节点(数据));
大小++;
返回true;
而不是:
int diff = val.compareTo(n.getData());
if (diff < 0)
n.setLeft(addHelper(n.getLeft(), val));
int diff=val.compareTo(n.getData());
如果(差异<0)
n、 setLeft(addHelper(n.getLeft(),val));
显然,这会导致树构建得更深,因此当您试图读回它时,会得到一个
StackOverflowerError
。您的树根本不平衡,已退化为一个链表。由于您按顺序添加,它将继续添加到右侧,并且由于没有尝试平衡,节点将包含只有对的孩子
若要修复,请查看一些或以不同的顺序添加以使其平衡。不平衡的树效率低下,并且会降低算法的速度,因为查找和插入将在O(n)而不是O(log n)中进行时间。
StackOverflowerError
仅仅意味着您的程序超出了堆栈大小。这个错误是递归调用的最大危险,从发布的堆栈跟踪中我们可以看到,实际上它是BinarySearchtTree.heightHelper
(第184行和第185行都进行递归调用)
所以我们剩下三个问题:
heightHelper
的调用太多:每次递归调用都会推送另一个堆栈帧,此时没有空间进行另一个调用-ss
参数调整JVM多好的标题啊!我很高兴impressed@martialdidit:lolz..每个人都是:)史上关于StackOverflow的最好的问题。我花了很长时间才看到评论中的连接,我得到了一个StackOverflower错误。@atmin不是无限的,只是很深。如果它是无限的,每次都会出错。
if (n.getData().compareTo(data) > 0) {
if (n.getLeft() == null) {
n.setLeft(new BSTNode<E>(data));
size++;
return true;
int diff = val.compareTo(n.getData());
if (diff < 0)
n.setLeft(addHelper(n.getLeft(), val));