【发布时间】:2021-06-02 15:49:39
【问题描述】:
我正在尝试使用 Java 实现二叉搜索树。我要创建的功能之一是删除功能。这将包含两种方法,一种称为 delete,另一种称为 getNodeToDelete。 getNodeToDelete 方法是 delete 方法的辅助函数。
getNodeToDelete 方法是递归的,基本上返回用户想要从树中删除的节点。使用从这个 getNodeToDelete 方法返回的节点,非递归 delete 方法基本上会根据不同的情况(例如,它是叶节点,是否是根节点等)。
这是非递归的删除方法:
/**
* Deletes the relevant node (according to the key inputted by the user), using two helper functions:
* getNodeToDelete(int deleteKey, Node root) and getMinRight(Node nodeToDelete).
* @param key
*/
public void delete(int key) {
if (root.left == null && root.right == null) {
if (root.key == key) {
root = null;
System.out.println("It reached the first if-statement of the delete() method.");
}
}
Node nodeToDelete = getNodeToDelete(key, root); //The node that is returned from its helper function.
System.out.println("This is the node to delete: " + nodeToDelete.key);
if (nodeToDelete.right == null && nodeToDelete.left == null) { //If the nodeToDelete is a leaf.
nodeToDelete = null;
// System.out.println("This is the key of the deleted node: " + nodeToDelete.key);
return;
} else if (nodeToDelete.right == null) { //If the nodeToDelete has an empty right tree.
Node immediateLeftNode = nodeToDelete.left;
nodeToDelete.key = immediateLeftNode.key;
nodeToDelete.left = immediateLeftNode.left;
nodeToDelete.right = immediateLeftNode.right;
} else if (nodeToDelete.right != null) { //If the nodeToDelete has a non-empty right tree
if (nodeToDelete.right.left == null) { //If the left branch of the right branch of nodeToDelete is empty.
nodeToDelete.key = nodeToDelete.right.key;
nodeToDelete.right = nodeToDelete.right.right;
} else {
Node replacementNode = getMinRight(nodeToDelete);
nodeToDelete.key = replacementNode.key;
}
}
}
这是递归的getNodeToDelete方法:
/**
* Assumption: the key does exist in the tree.
* Returns the node that the user wants to delete, based on the key that the user inputs.
* @param deleteKey
* @param startingRoot
* @return
*/
public Node getNodeToDelete(int deleteKey, Node startingRoot) {
if (startingRoot == null) {
return null;
}
if (startingRoot.key == deleteKey) {
return startingRoot;
}
if (deleteKey < startingRoot.key) {
getNodeToDelete(deleteKey, startingRoot.left);
}
getNodeToDelete(deleteKey, startingRoot.right);
return startingRoot;
}
问题是,辅助函数 getNodeToDelete 向下遍历树到其节点之一,例如值为 -12 的叶节点。然后它返回该节点,但递归方法 getNodeToDelete 似乎没有结束。然后它再次遍历回到根节点,始终导致返回的值是根节点。
我知道在 Java 中实现二叉搜索树有很多不同的方法,但是这个递归问题困扰着我,我真的很想知道失败背后的原因。
如果您需要更多说明,请告诉我。谢谢
【问题讨论】:
-
删除一个节点是什么意思?是否要删除该节点下的整个子树?或者只是那个节点,然后“重新连接”子树?
-
我只想删除该节点并重新连接子树。顺便说一句,你是在删除之前写答案的人吗?
标签: java recursion binary-search-tree