Java 在二叉搜索树中搜索节点时如何处理空检查

Java 在二叉搜索树中搜索节点时如何处理空检查,java,data-structures,binary-search-tree,optional,Java,Data Structures,Binary Search Tree,Optional,我有以下代码来搜索BST中的节点: private Node<AnyType> searchAndGetNode(AnyType value) { Node<AnyType> currentNode = root; while(currentNode != null && currentNode.getData() != null) { if (value.compareTo(currentNode

我有以下代码来搜索BST中的节点:

private Node<AnyType> searchAndGetNode(AnyType value) {
        Node<AnyType> currentNode = root; 
        while(currentNode != null && currentNode.getData() != null) {
            if (value.compareTo(currentNode.getData()) == 0) {
                return currentNode;
            } else if (value.compareTo(currentNode.getData()) < 0) {
                currentNode = currentNode.getLeft();
            } else {
                currentNode = currentNode.getRight();
            }
        }
        return null;
    }
private Node searchAndGetNode(AnyType值){
节点currentNode=root;
while(currentNode!=null&¤tNode.getData()!=null){
if(value.compareTo(currentNode.getData())==0){
返回当前节点;
}else if(value.compareTo(currentNode.getData())<0){
currentNode=currentNode.getLeft();
}否则{
currentNode=currentNode.getRight();
}
}
返回null;
}

我知道Optional.ofNullable()可以获取可选对象,然后使用isPresent()避免空检查。但是在上述方法中,我想不出任何简洁的方法来避免while循环中的空检查比较。我正在使用Java8。请建议。

如果不是在
while
条件下,而不是在
getLeft()
getRight()
条件下(无论是在调用它还是在它内部),您必须在某处检查它。您选择的选项比IMHO更好,因为您只检查一次,而其他选项需要多次检查。

如果不是在
while
条件下,您必须在某处检查它,而不是在
getLeft()
getRight()
条件下(无论是在调用它还是在它内部)。您选择的选项更好,因为您只检查一次,而其他选项需要多次检查。

您应该删除
&¤tNode.getData()!=null
是条件的一部分,因为在二叉树中存在null值是没有意义的(您不能在null上调用
compareTo
,因此您将在何处将其插入树中?)。除此之外,您的空检查没有问题

但是,对于性能,您不应该为每个值调用两次
compareTo
,而应该调用一次并检查结果:

int cmp = value.compareTo(currentNode.getData());
if (cmp == 0) {
    return currentNode;
} else if (cmp < 0) {
    currentNode = currentNode.getLeft();
} else { // cmp > 0
    currentNode = currentNode.getRight();
}
int-cmp=value.compareTo(currentNode.getData());
如果(cmp==0){
返回当前节点;
}否则如果(cmp<0){
currentNode=currentNode.getLeft();
}else{//cmp>0
currentNode=currentNode.getRight();
}

您应该删除
&¤tNode.getData()!=null
是条件的一部分,因为在二叉树中存在null值是没有意义的(您不能在null上调用
compareTo
,因此您将在何处将其插入树中?)。除此之外,您的空检查没有问题

但是,对于性能,您不应该为每个值调用两次
compareTo
,而应该调用一次并检查结果:

int cmp = value.compareTo(currentNode.getData());
if (cmp == 0) {
    return currentNode;
} else if (cmp < 0) {
    currentNode = currentNode.getLeft();
} else { // cmp > 0
    currentNode = currentNode.getRight();
}
int-cmp=value.compareTo(currentNode.getData());
如果(cmp==0){
返回当前节点;
}否则如果(cmp<0){
currentNode=currentNode.getLeft();
}else{//cmp>0
currentNode=currentNode.getRight();
}

您无法避免空检查。您必须有一些条件来确定何时完成搜索树而未找到请求的节点。此检查是否将某些引用与null进行比较,或者询问某些可选项是否为空,这没有什么区别。

您无法避免null检查。您必须有一些条件来确定何时完成搜索树而未找到请求的节点。此检查是否将某些引用与null进行比较,或者询问某些可选项是否为空,这没有什么区别。

我认为您的代码应该正常工作。当您输入不存在或具有空值的右/左子级时,您只需退出while循环。循环需要一个结束条件,null是位置

我只建议换一个

currentNode.getData() != null
使用此节点的方法,如
currentNode.hasData()
。这将隐藏您的逻辑并更具可读性:)

private Node searchAndGetNode(AnyType值){
节点currentNode=root;
while(currentNode!=null&¤tNode.getData()!=null){
int comparedValue=value.compareTo(currentNode.getData());//比较一次。因为这是一个int
如果(比较值==0){
返回当前节点;
}否则如果(比较值<0){
currentNode=currentNode.getLeft();
}否则{
currentNode=currentNode.getRight();
}
}
返回null;
}

我认为您的代码可以正常工作。当您输入不存在或具有空值的右/左子级时,您只需退出while循环。循环需要一个结束条件,null是位置

我只建议换一个

currentNode.getData() != null
使用此节点的方法,如
currentNode.hasData()
。这将隐藏您的逻辑并更具可读性:)

private Node searchAndGetNode(AnyType值){
节点currentNode=root;
while(currentNode!=null&¤tNode.getData()!=null){
int comparedValue=value.compareTo(currentNode.getData());//比较一次。因为这是一个int
如果(比较值==0){
返回当前节点;
}否则如果(比较值<0){
currentNode=currentNode.getLeft();
}否则{
currentNode=currentNode.getRight();
}
}
返回null;
}
但我想不出任何简洁的方法来避免空检查比较 在while循环中

没有问题=空


但是您可以使用一个带有leaf和节点的接口(并使用Java8的默认方法)

然后,您可以调用
isEmpty()
检查是否已从
searchAndGetNode
方法返回节点或叶

有些人可能会认为,
isEmpty()
也可以在
接口中实现

但我想不出任何简洁的方法来避免空检查比较 在while循环中

T
class BST<T extends Comparable<? super T>> {

    ...

    private Tree<T> searchAndGetNode(T value) {
        Tree<T> currentNode = root; 
        while(!currentNode.isEmpty()) {
            int cmp = value.compareTo(currentNode.getData());
            if (cmp == 0) {
                return currentNode;
            } else if (cmp < 0) {
                currentNode = currentNode.getLeft();
            } else {
                currentNode = currentNode.getRight();
            }
        }
        return currentNode; //it will be a Leaf at this point
    }

}