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

时间:2016-08-09 03:57:33

标签: java binary-search-tree

我正在尝试从二进制搜索树中删除节点。除了一个特定的情况,我可以成功删除树上的任何其他节点。如果目标节点有2个子节点,并且左子节点具有右子树,我可以找到正确的替换节点并将值切换到目标节点,但是永远不会删除替换节点。

Binary Search Tree

看看上面的图片,如果我尝试删除17,程序将正确导航到13并用13替换17,但它不会删除原来的13,因为它应该。

我附上了我的删除方法和那些引用的方法。

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 个答案:

答案 0 :(得分:1)

考虑这部分代码:

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

您正在寻找替代品,并使rep指向它。然后,基本上你正在做的是让rep指向null。这不会删除节点!父母仍然指着它!

您的代码中有几个地方沿着这些方向做某事。在Java实现中,您希望从树中删除节点的方式是更改父项指向的内容。垃圾收集器负责其他细节。我希望解决这个问题可以帮助您解决问题!