在BinarySearchTree中获取前任的问题

时间:2018-09-27 21:39:18

标签: java binary-search-tree

这是我的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,然后由于空指针异常而失败。为什么抛出空指针?

2 个答案:

答案 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 == keytrue到达您要查找的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()

剩下要做的就是何时确实会发生这种情况,并找到另一种无故障的处理方法!我在上面放了一些提示,但是由于您似乎真的在学习,因此我将让您找出更详细的信息:)