Java 从二叉搜索树中删除元素

Java 从二叉搜索树中删除元素,java,binary-search-tree,Java,Binary Search Tree,我正在做一个作业,实现自己的二叉搜索树。问题是,我们有自己的节点实现,它的父节点不能直接访问 我一直在寻找答案,但我不想完全照搬解决方案,尽管如此,我似乎仍然没有找到正确的答案。我错过了一些未删除元素的情况 你能帮帮我吗?我做错了什么 这是删除方法: void remove(E elem) { if(elem != null){ if (root != null && contains(elem)) { removeFromSu

我正在做一个作业,实现自己的二叉搜索树。问题是,我们有自己的节点实现,它的父节点不能直接访问

我一直在寻找答案,但我不想完全照搬解决方案,尽管如此,我似乎仍然没有找到正确的答案。我错过了一些未删除元素的情况

你能帮帮我吗?我做错了什么

这是删除方法:

void remove(E elem) {
    if(elem != null){
        if (root != null && contains(elem)) {  
            removeFromSubtree(elem, root, null);  
        }
    }
}

void removeFromSubtree(E elem, Node<E> current, Node<E> parent) {

    if(elem.less(current.contents)){
        if(current.left == null) return ;
        removeFromSubtree(elem, current.left, current);
    } else if(elem.greater(current.contents)){
        if(current.right == null)return;
        removeFromSubtree(elem, current.right, current);
    } else {
        if(current.left != null && current.right != null){
            //both children
            if(parent == null){
                Node<E> n = new Node<>(null, null);
                n.left = root;
                removeFromSubtree(root.contents, n, null);
                root = n.left;
                root.setParent(null);
            }
            E min = subtreeMin(current.right);
            current.contents = min;
            removeFromSubtree(min, current.right, current);
        } else if(current.left != null){
            //left child
            if (parent == null) {
                    root = current.left;
                    current.left.setParent(null);
                    return ;
                }
            setParentChild(current, parent, current.left);
        } else if(current.right != null){
            //right child
            if (parent == null) {
                root = current.right;
                current.right.setParent(null);
                return ;
            }
            setParentChild(current, parent, current.right);
        } else {
            if (parent == null) {
                root = null;
                return ;
            }
            setParentChild(current, parent, null);
        }
    }
}
void删除(E元素){
if(elem!=null){
如果(root!=null&&contains(elem)){
removeFromSubtree(元素、根、空);
}
}
}
void removeFromSubtree(元素、节点当前、节点父节点){
if(元素较少(当前内容)){
if(current.left==null)返回;
removeFromSubtree(elem,current.left,current);
}else if(元素更大(当前内容)){
if(current.right==null)返回;
removeFromSubtree(elem,current.right,current);
}否则{
if(current.left!=null&¤t.right!=null){
//两个孩子
如果(父项==null){
节点n=新节点(null,null);
n、 左=根;
removeFromSubtree(root.contents,n,null);
根=n.左;
root.setParent(null);
}
E最小值=次行程最小值(当前右侧);
current.contents=min;
removeFromSubtree(最小,当前。右侧,当前);
}else if(current.left!=null){
//左撇子
如果(父项==null){
root=current.left;
current.left.setParent(空);
返回;
}
setParentChild(当前,父,当前.左);
}else if(current.right!=null){
//对的孩子
如果(父项==null){
root=current.right;
current.right.setParent(空);
返回;
}
setParentChild(当前,父,当前.右);
}否则{
如果(父项==null){
root=null;
返回;
}
setParentChild(当前、父级、空);
}
}
}
节点使用通用接口

class Node<E extends DSAComparable<E>>
类节点
只有比较的方法。看起来像这样

interface DSAComparable<E extends DSAComparable<E>> {
    boolean less(E other); 
    boolean greater(E other);
    boolean equal(E other);
}
接口DSA可比较{
布尔少(E其他);
布尔更大(E其他);
布尔相等(E其他);
}
我在remove中使用了另一种方法来设置节点的父节点的子节点,这取决于它的左子节点还是右子节点

void setParentChild(Node<E> node, Node<E> parent,Node<E> value){
    if(parent!= null){
        if (parent.left == node) {
            parent.left = value;
        } else {
            parent.right = value;
        }
        if(value!= null) value.setParent(parent);
    }
}
void setParentChild(节点节点、节点父节点、节点值){
如果(父项!=null){
if(parent.left==节点){
parent.left=值;
}否则{
parent.right=值;
}
if(value!=null)value.setParent(parent);
}
}

方法subtreeMin(Node Node)查找子树中最小的值(最左边的)

理解代码并不容易,因为它仍然缺乏细节

我会提到这样一个二进制搜索树的实现,你可以在网上找到


例如,请参见。

您到底需要什么?您报告的大多数代码调用的方法不是来自JDK。如果没有任何额外的细节,几乎不可能在某些情况下,当元素应该被移除时却没有被移除。我不知道哪些条件我没有包括在内。我介绍了childen null、任一child null和no child null,以及删除root时的情况。我还是不明白。所以我的问题是,是否有我没有包含的条件?您必须提供其他方法的实现。例如,您如何处理
elem.less()
?我编辑了答案,希望它会有所帮助。如果(root!=null&&contains(elem))中包含
else
,可能会有所帮助。然后,如果有一个值始终没有被删除,那么您可以在该值中打断,以检查事物的状态。我的直觉是,contains没有返回你一直期待的结果。