这是我的getBefore方法
public Node getBefore() {
return getBeforeHelper(root, this.data);
}
public Node getBeforeHelper(Node node, K key) {
Node current = null;
if(node != null) {
if(node.data == key) {
if(node.left != null) {
current = node.left;
while(current.right != null) {
current = current.right;
}
System.out.println(current.get());
return current;
}
}
else if(lessThan.test(key, node.data)) {
return getBeforeHelper(node.left, key);
}
else if(lessThan.test(node.data, key)) {
return getBeforeHelper(node.right, key);
}
}
else {
return null;
}
return current;
}
这是未能通过的Junit测试
@Test
public void beforeBST() {
BinarySearchTree<Integer> bst = new BinarySearchTree<>((Integer x, Integer y) -> x < y);
assertTrue(bst.isEmpty());
int[] a = new int[] { 12, 4, 18, 5, 11, 8, 15, 9, 17, 20, 3, 13, 19, 2, 14, 7, 6, 10, 1, 16 };
int n = a.length;
for (Integer key : a)
bst.insert(key);
assertNull(bst.search(1).getBefore());
for (int i = 2; i <= n; i++) {
System.out.println(bst.search(2).getBefore());
assertTrue(i - 1 == bst.search(i).getBefore().get());
}
}
它在最后一个for循环中到达assertTrue,然后由于空指针异常而失败。为什么抛出空指针?
答案 0 :(得分:0)
当方法getBeforeHelper找到具有您的键的元素时,它将尝试获取左元素。如果您的左元素不存在,那将不起作用。在这种情况下,getBeforeHelper返回的“当前”为null。 在这种情况下,您可以对此空元素调用get()并获取一个空指针异常。
答案 1 :(得分:0)
您似乎最终会遇到以下情况:
// this yields null
// v v
assertTrue(i - 1 == bst.search(i).getBefore().get());
// ^ ^
// attempt to access a method belonging to a null reference
考虑在getBeforeHelper
中您具有以下情况:
node != null
(在测试中总是true
会引起问题)node.data == key
(true
到达您要查找的Node
时)node.left == null
(想一想:什么时候发生?)在这种情况下,您实际上将得到getBeforeHelper
方法的以下主体(通过丢弃您确实通过else
测试的所有if
块并丢弃所有内容测试失败的if
块中的一个):
public Node getBeforeHelper(Node node, K key) {
Node current = null;
if(node != null) { // true
if(node.data == key) { // true
if(node.left != null) { // false
}
}
}
return current;
}
好吧,就在那儿,您要返回null
。
然后在下一行,尝试在您的断言中求值null.get()
。
剩下要做的就是何时确实会发生这种情况,并找到另一种无故障的处理方法!我在上面放了一些提示,但是由于您似乎真的在学习,因此我将让您找出更详细的信息:)
。