簡體   English   中英

在二進制搜索樹中搜索節點時如何處理空檢查

[英]How to handle null check when searching for a node in Binary Search Tree

我有以下代碼在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;
    }

我知道Optional.ofNullable()獲取Optional對象,然后使用isPresent()避免進行空檢查。 但是我想不出任何巧妙的方法來避免在上述方法的while循環中進行空檢查比較。 我正在使用Java8。請提出建議。

您應該刪除條件中的&& currentNode.getData() != null部分,因為在二叉樹中沒有null值是沒有意義的(您不能在null上調用compareTo ,因此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();
}

但是我想不出任何巧妙的方法來避免在while循環中進行空檢查比較

!=null沒什么錯。


但是您可以改為使用帶Leafs和Nodes的接口(並在Java 8中使用默認方法)。

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
    }

}

然后,您的代碼中就不再需要進行空檢查(在這一點上,@ Boann之后,您將在BST中存儲null引用嗎?):

 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 } } 

然后,您可以只調用isEmpty()來檢查是否從searchAndGetNode方法返回了Node或Leaf。

有人可能會說isEmpty()也可以在Tree接口中實現。

您必須在某個地方檢查它,如果不是在while條件下, getLeft()getLeft()getRight() (無論在調用它時還是在它內部)檢查它。 您選擇的選項更好,恕我直言,因為您只檢查一次,而其他選擇則需要多次檢查。

您無法避免執行空檢查。 您必須具備一些條件才能確定何時完成搜索樹而沒有找到請求的節點。 此檢查是將某些引用與null進行比較還是詢問某些Optional是否為空沒有區別。

我認為您的代碼可以正常工作。 當您輸入不存在或值為空的右/左子項時,只需退出while循環即可。 您需要在循環中使用結束條件,而null是地方。

我只建議更換

currentNode.getData() != null

使用此節點的方法,例如currentNode.hasData() 這將隱藏您的邏輯,並且更具可讀性:)

     private Node<AnyType> searchAndGetNode(AnyType value) {
        Node<AnyType> currentNode = root; 
        while(currentNode != null && currentNode.getData() != null) {
            int comparedValue = value.compareTo(currentNode.getData());//compare once. Because this is a int
            if (comparedValue  == 0) {
                return currentNode;
            } else if (comparedValue  < 0) {
                currentNode = currentNode.getLeft();
            } else {
                currentNode = currentNode.getRight();
            }
        }
        return null;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM