我正在写一个二叉树。在尝试删除有两个子节点的节点时,我编写了一个方法来搜索右子节点的最左边节点。
我收到一个奇怪的错误 - 在返回值之前,我似乎再次进入while循环,尽管条件不满足(标志为false)。在while循环之后,它以递归方式调用自身并最终得到一个空节点,因为它已经进入树中太远了。
有人可以说出为什么会这样吗?
protected Key rlmost (BSTreeNode node){
BSTreeNode leafnode = null;
if ((node.right!=null)&&(node.left!=null)&&(flag==false)){
flag = true; // set flag to true
System.out.println("left node" + node.left.kvPair.key);
rlmost(node.left);
System.out.println();
}
while (flag==true){
if (node.right != null){
System.out.println("right node" + node.right.kvPair.key);
rlmost(node.right);
}
else {
leafnode = node;
System.out.println("rlmost node" + leafnode.kvPair.key);
flag = false;
}
}
return leafnode.kvPair.key;
}
答案 0 :(得分:1)
我认为问题在于你的递归。让我们假设一个非常简单的结构。没有左或右的节点(均为空)。
首先,leafnode以null开头。鉴于结构,我们不能进入if-block。鉴于flag == false,我们无法进入while循环。所以当你回来时,你会得到一份NPE。
如果我们使这个更复杂一点,如果一个节点有一个左右,但没有孙子,我们将得到同样的问题。
你会遇到第一个if-block。你使用flag == true来递归,但是将递归的结果抛给左边。在第一次递归调用时,您无法进入第一个if-block。你将进入while循环,然后进入else-block。 leafnode设置为节点。您将返回第一个呼叫(这是在if-block中)。此时leafnode仍为null。繁荣,NPE。
如何初始化leafnode取决于您。您应该将其设置为rlmost的递归调用。