当前位置: 首页 > 知识库问答 >
问题:

二进制搜索树节点删除未删除替换Java

南宫书
2023-03-14

我正在尝试从二叉查找树中删除节点。我可以成功地删除树上的任何其他节点,除了一个特殊的情况。如果目标节点有两个子节点,左边的子节点有右边的子树,我可以定位正确的替换节点,并将值切换到目标节点,但替换节点永远不会被删除。

看看上面的图片,如果我尝试删除17,程序将正确地导航到13,并用13替换17,但它不会像预期的那样删除原来的13。

我附加了我的remove方法和其中引用的方法。

public Node root;    

    public void delete(int value){

    Node node = new Node<>(value);
    Node temp;

    if(root == null) {
        System.out.println("The tree is already empty!");           //tree is empty
        return;     
    }

    if (root.value == node.value) {                                 //Root is target value
        temp = node.left;

        if(temp.right == null){
            node.value = temp.value;
            temp = null;
        }
        else{
            while(temp.right != null){
                temp = temp.right;
            }
            node.value = temp.value;
            temp = null;
        }
        return;
    }
    deleteRec(root, node);
}

private void deleteRec(Node lastRoot, Node node){

    Node temp;

    if (lastRoot.value >= node.value){

        if (lastRoot.left.value == node.value){
            node = lastRoot.left;
            if(node.left == null && node.right == null){        //No children
                node = null;
                lastRoot.left = null;
            }
            else if(node.left == null && node.right != null){   //Right Child
                lastRoot.left = node.right;
                node = null;
                lastRoot.left = null;
            }
            else if(node.left != null && node.right == null){   //Left Child
                lastRoot.left = node.left;
                node = null;
            }
            else{                                               //Two Children

                if(node.left.right == null){
                    node.value = node.left.value;
                    node.left = node.left.left;
                    node.left = null;
                }
                else{
                    node = findReplacement(node.left);
                    lastRoot.left.value = node.value;
                    node.left = null;
                }
            }
        }
        else{
            deleteRec(lastRoot.left, node);
        }
    }
    else{
        if (lastRoot.right.value == node.value){
            node = lastRoot.right;
            if(node.left == null && node.right == null){        //No Children
                node = null;
                lastRoot.right = null;
            }
            else if(node.left == null && node.right != null){   //Right Child
                lastRoot.left = node.right;
                node = null;
                lastRoot.right = null;
            }
            else if(node.left != null && node.right == null){   //Left Child
                lastRoot.right = node.left;
                node = null;
            }
            else{                                               //Two Children

                if(node.left.right == null){
                    node.value = node.left.value;
                    node.left = node.left.left;
                    node.left = null;
                }
                else{
                    node = findReplacement(node.left);
                    lastRoot.left.value = node.value;
                    node.left = null;
                }
            }
        }
        else{
            deleteRec(lastRoot.right, node);
        }
    }
}

private Node findReplacement(Node node) {

    while(node.right != null){
        node = node.right;
    }        
    return node;
}

这是我的Node类:

 public class Node<T> {
    public int value;
    public Node left;
    public Node right;
    public Node parent;

    public Node(int value) {
        this.value = value;
    }
}

共有1个答案

凌恩
2023-03-14

考虑代码的这一部分:

Node rep = findReplacement(node.left);
node.value = rep.value;
rep = null;

您正在寻找替换项,并使rep指向它。然后,本质上,您正在做的是使rep指向null。这不会删除节点!父节点仍然指向它!

在您的代码中有几个地方,您正在按照这些思路做一些事情。在这个Java实现中,您需要从树中删除节点的方式是通过更改父节点指向的内容。垃圾收集器负责其他细节。我希望解决这个问题可以帮助您解决问题!

 类似资料:
  • 目前,我在理解如何在没有传递节点时从二进制搜索树中删除节点时遇到了一个问题。我有两个类,BSTSet和BSTNode,每个类都有一个remove方法。。 当我被传递一个节点时,我理解删除方法,但当我在根上调用remove方法并试图从node类中删除节点时,我不知道从何处开始。有人能告诉我吗?谢谢如果您想了解更多信息,请询问。

  • 我的删除方法由4个if语句组成,用于处理二叉查找树中的4种不同类型的删除。不确定哪里错了,但当我检查它时,它没有删除任何节点。如果赞赏,任何帮助。提前感谢' 我怀疑问题在于我试图将节点删除替换为空 }

  • 我试着删除二叉查找树的节点,当我打印出来的时候,我得到的结果实际上不是这个删除,实际上可以删除二叉树本身的任何键。 我是二进制搜索树的新手。有人能帮我写代码吗?我们将感谢您的帮助。 谢谢 完整代码

  • 我目前正在做一个学校项目,我必须为二叉搜索树编写一些辅助函数。其中一个函数从树中删除了一个节点。我正在尝试运行一些测试用例,但似乎无法让它们正常工作。我知道这个问题与我如何使用指针有关,但我不太确定我哪里出错了。 这是代码: 注意:我没有包括leftRoot()函数,但它相当简单,我知道它做了它应该做的事情(返回子树中最左边的根)下面是我的教授给我们的测试remove函数的代码部分: 如果有必要,

  • 主要内容:src/runoob/binary/BSTRemove.java 文件代码:本小节介绍二分搜索树节点的删除之前,先介绍如何查找最小值和最大值,以及删除最小值和最大值。 以最小值为例(最大值同理): 查找最小 key 值代码逻辑,往左子节点递归查找下去: ... // 返回以node为根的二分搜索树的最小键值所在的节点 private Node minimum (Node node ) {     if ( node. left == null )         retu

  • 我在C中实现了一个二进制搜索树。 对于delete方法,除了最后一种情况外,其他情况都可以使用,即唯一的树是父树,并且它指向两个空的子树。现在的问题是:我希望在删除子树后,打印出父树的左子树和右子树等于什么。它们和父项都应该为NULL,但是当我试图输出这些值时,我得到了一个状态访问冲突。 下面是有关删除的代码。我希望删除父节点,并设置树- 主要: