Java 递归二叉搜索树删除方法

Java 递归二叉搜索树删除方法,java,recursion,binary-search-tree,Java,Recursion,Binary Search Tree,首先,这是家庭作业,所以把它放在那里 我应该用特定的方法实现一个二叉搜索树: 空插入(字符串)、布尔删除(字符串)和布尔查找(字符串) 我已经能够成功地编程和测试插入和查找方法,但在删除时遇到困难 在我的程序中,remove实际上并没有从树中删除任何内容,我相信这是因为它只引用当前节点的本地创建,但我可能错了。我想我可以实现我需要测试的不同案例的逻辑(可能需要删除一个有两个子节点的案例的帮助,但我认为我在概念上得到了它),我主要是想了解我需要做什么不同的事情,以便在 current = null

首先,这是家庭作业,所以把它放在那里

我应该用特定的方法实现一个二叉搜索树:

空插入(字符串)、布尔删除(字符串)和布尔查找(字符串)

我已经能够成功地编程和测试插入和查找方法,但在删除时遇到困难

在我的程序中,remove实际上并没有从树中删除任何内容,我相信这是因为它只引用当前节点的本地创建,但我可能错了。我想我可以实现我需要测试的不同案例的逻辑(可能需要删除一个有两个子节点的案例的帮助,但我认为我在概念上得到了它),我主要是想了解我需要做什么不同的事情,以便在

current = null; // case
以下是我到目前为止得到的信息:

public boolean remove(String title)
{
    return remove(root, title);
}
private boolean remove(BSTNode current, String title)
{
    if (current == null)
    {
        return false;
    }
    if (current.data == title)
    {
    if (current.left_child !=null && current.right_child != null)
    {
        return true;  // returning true since I haven't finished writing this case
    }
    else if (current.left_child == null && current.right_child == null)
        {
        current = null;  // this should remove the node from tree but it doesn't
        return true; 
    }

    else if (current.left_child != null && current.right_child == null)
    {
        current = current.left_child;    // don't think this is right
        return true;
    }
    else if (current.right_child != null && current.left_child == null)
    {
        current = current.right_child;   // not sure about this
        return true;
    }

    }
root = current;
if (title.compareToIgnoreCase(current.data) == -1)
{
    return remove(current.left_child, title);
}
    else 
{
    return remove(current.right_child, title);
}
}

非常感谢任何知识。

节点由其父节点引用(除根节点外,该节点由BST本身引用)。要从树中删除节点,需要将父节点中的引用设置为
null

您现在要做的是:

Before:
parent.left ---> node <--- current

After setting current = null:
parent.left ---> node      current ---> null
By递归很烦人,因为您需要一个同时返回节点及其父节点的方法。您需要一些简单的内部类来解决此问题:

private class NodeAndParent {
    public BSTNode node;
    public BSTNode parent;
    public NodeAndParent(BSTNode node, BSTNode parent) {
        this.node = node;
        this.parent = parent;
    }
}

private boolean find(String title, NodeAndParent current) {
    if (current.node == null) {
        return false; // not found
    } else {
        int compare = title.compareToIgnoreCase(current.node.data);
        if (compare == 0) {
            return true; // found
        } else {
            current.parent = current.node;
            if (compare < 0) {
                current.node = current.node.left;
            } else {
                current.node = current.node.right;
            }
        }
    }
}

private boolean remove(String title) {
    NodeAndParent nodeAndParent = new NodeAndParent(root, null);
    boolean found = find(title, nodeAndParent);
    if (!found) {
        // title was not found
    } else if (nodeAndParent.parent == null) {
        // found the root
    } else {
        // found another node
    }
}    
私有类节点和客户端{
公共BST节点;
公共节点父节点;
公共节点和父节点(BSTNode节点、BSTNode父节点){
this.node=节点;
this.parent=parent;
}
}
私有布尔查找(字符串标题、节点和当前不一致){
if(current.node==null){
返回false;//未找到
}否则{
int compare=title.compareToIgnoreCase(current.node.data);
如果(比较==0){
返回true;//找到
}否则{
current.parent=current.node;
如果(比较<0){
current.node=current.node.left;
}否则{
current.node=current.node.right;
}
}
}
}
私有布尔删除(字符串标题){
NodeAndParent NodeAndParent=新的NodeAndParent(根,空);
布尔查找=查找(标题、节点和属性);
如果(!找到){
//找不到标题
}else if(nodeAndParent.parent==null){
//找到根
}否则{
//找到另一个节点
}
}    

非常感谢您的反馈。你所描述的就是我想象中的情况。我认为我的问题是我没有在类中定义父节点(讲师暗示这是一个不太优雅的解决方案,所以如果我们可以避免的话)。我试图了解如何在插入方法中不设置某种引用类型的情况下,告诉“当前”节点(base case=root)有关父节点的信息。我认为这样的实现是不可能的,因此我必须在插入中包含一个父节点,以跟踪哪个节点是当前节点的父节点,这样我就可以将其引用更改为null。@user2948847实际上,您不应该在每个节点中存储父节点引用,这是不必要的。请参阅我关于如何查找节点及其父节点的更新。我会选择循环版本,但如果必须使用递归,它会有点棘手。您可以通过在我称为
find
的方法中执行remove来摆脱内部类,但这违反了“关注点分离”的良好实践(单个方法不应同时查找和删除节点)。
private class NodeAndParent {
    public BSTNode node;
    public BSTNode parent;
    public NodeAndParent(BSTNode node, BSTNode parent) {
        this.node = node;
        this.parent = parent;
    }
}

private boolean find(String title, NodeAndParent current) {
    if (current.node == null) {
        return false; // not found
    } else {
        int compare = title.compareToIgnoreCase(current.node.data);
        if (compare == 0) {
            return true; // found
        } else {
            current.parent = current.node;
            if (compare < 0) {
                current.node = current.node.left;
            } else {
                current.node = current.node.right;
            }
        }
    }
}

private boolean remove(String title) {
    NodeAndParent nodeAndParent = new NodeAndParent(root, null);
    boolean found = find(title, nodeAndParent);
    if (!found) {
        // title was not found
    } else if (nodeAndParent.parent == null) {
        // found the root
    } else {
        // found another node
    }
}