5

我正在尝试为我一直在研究的 BST 结构实现删除方法。下面是查找、插入和删除方法的代码:

public class BST {
    BSTNode root = new BSTNode("root");

    public void insert(BSTNode root, String title){
        if(root.title!=null){

            if(title==root.title){
                //return already in the catalog
            }
            else if(title.compareTo(root.title)<0){

                if(root.leftChild==null){
                    root.leftChild = new BSTNode(title);
                }
                else{
                    insert(root.leftChild,title);
                }
            }
            else if(title.compareTo(root.title)>0){
                if(root.rightChild==null){
                    root.rightChild = new BSTNode(title);
                }
                else{
                    insert(root.rightChild,title);
                }
            }
        }
    }

    public void find(BSTNode root, String title){
        if(root!= null){
            if(title==root.title){
                //return(true);
            }
            else if(title.compareTo(root.title)<0){
                find(root.leftChild, title);
            }
            else{
                find(root.rightChild, title);
            }
        }
        else{
            //return false;
        }
    }

    public void remove(BSTNode root, String title){
        if(root==null){
            return false;
        }
        if(title==root.title){
            if(root.leftChild==null){
                root = root.rightChild;
            }
            else if(root.rightChild==null){
                root = root.leftChild;
            }
            else{
                //code if 2 chlidren remove
            }
        }
        else if(title.compareTo(root.title)<0){
            remove(root.leftChild, title);
        }
        else{
            remove(root.rightChild, title);
        }
    }
}

有人告诉我,我可以使用 insert 方法来帮助我使用 remove 方法,但我只是没有看到如何获取最小/最大元素,然后用该值替换我要删除的元素,然后递归删除我取替换值的节点,同时仍保持 O(logn) 复杂性。任何人有任何我错过的想法或明显的漏洞,或者在我对这个问题大发雷霆时还有什么有用的吗?

编辑:我使用答案的想法想出了这个,我相信这会起作用,但我收到一个错误,我的方法(不仅仅是删除)必须返回字符串,这是代码的样子,我认为这是退货声明??

public String remove(BSTNode root, String title){
            if(root==null){
                return("empty root");
            }
            if(title==root.title){
                    if(root.leftChild==null){
                            if(root.rightChild==null){
                                    root.title = null;
                                    return(title+ "was removed");
                            }
                            else{
                            root = root.rightChild;
                            return(title+ "was removed");
                            }
                    }
                    else if(root.rightChild==null){
                            root = root.leftChild;
                            return(title+ "was removed");
                    }
                    else{
                            String minTitle = minTitle(root);
                            root.title = minTitle;
                            remove(root.leftChild,minTitle);
                            return(title+ "was removed");
                    }
            }
            else if(title.compareTo(root.title)<0){
                    remove(root.leftChild, title);
            }
            else{
                    remove(root.rightChild, title);
            }
    }
4

6 回答 6

6
public void remove (String key, BSTNode pos)
    {
        if (pos == null) return;
        if (key.compareTo(pos.key)<0)
            remove (key, pos.leftChild);
        else if (key.compareTo(pos.key)>0)
            remove (key, pos.rightChild);
        else {
            if (pos.leftChild != null && pos.rightChild != null)
            {
                /* pos has two children */
                BSTNode maxFromLeft = findMax (pos.leftChild); //need to make a findMax helper 
                //"Replacing "  pos.key " with " maxFromLeft.key
                pos.key = maxFromLeft.key;
                remove (maxFromLeft.key, pos.leftChild);
            }
            else if(pos.leftChild != null) {
                /* node pointed by pos has at most one child */
                BSTNode trash = pos;
                //"Promoting " pos.leftChild.key " to replace " pos.key
                pos = pos.leftChild;
                trash = null;
            }
            else if(pos.rightChild != null) {
                /* node pointed by pos has at most one child */
                BSTNode trash = pos;
                /* "Promoting " pos.rightChild.key" to replace " pos.key */
                pos = pos.rightChild;
                trash = null;
            }
            else {
                pos = null;
            }
        }
    }

这是不平衡树的删除。我有 C++ 中的代码,所以我很快翻译了。不过可能会有一些小错误。您正在编码的树是否必须平衡?如果需要,我也有平衡移除。根据您问题的措辞,我不太确定。还要确保为 findMax() 添加一个私有辅助函数

于 2013-11-09T00:32:16.907 回答
4
void deleteTreeNode(int data){
    root = deleteTreeNode(root ,data);
}

private TreeNode deleteTreeNode(TreeNode root, int data) {
    TreeNode cur = root;
    if(cur == null){
        return cur;
    }
    if(cur.data > data){            
        cur.left = deleteTreeNode(cur.left, data);
    }else if(cur.data < data){
        cur.right = deleteTreeNode(cur.right, data);
    }else{          
        if(cur.left == null && cur.right == null){
            cur = null;
        }else if(cur.right == null){
            cur = cur.left;
        }else if(cur.left == null){
            cur = cur.right;
        }else{
            TreeNode temp  = findMinFromRight(cur.right);
            cur.data = temp.data;
            cur.right = deleteTreeNode(cur.right, temp.data);
        }
    }
    return cur;
}

private TreeNode findMinFromRight(TreeNode node) {
    while(node.left != null){
        node = node.left;
    }
    return node;
}
于 2016-03-24T07:25:13.717 回答
0

要比较 java 中的对象,请使用 .equals() 方法而不是“==”运算符

  if(title==root.title)
          ^______see here

你需要像这样使用

 if(title.equals(root.title)) 

或者如果您有兴趣忽略此案例,请遵循以下代码

 if(title.equalsIgnoreCase(root.title))
于 2013-11-09T00:11:10.317 回答
0
private void deleteNode(Node temp, int n) {
    if (temp == null)
        return;
    if (temp.number == n) {
        if (temp.left == null || temp.right == null) {
            Node current = temp.left == null ? temp.right : temp.left;
            if (getParent(temp.number, root).left == temp)
                getParent(temp.number, root).left = current;
            else
                getParent(temp.number, root).right = current;
        } else {
            Node successor = findMax(temp.left);
            int data = successor.number;
            deleteNode(temp.left, data);
            temp.number = data;
        }
    } else if (temp.number > n) {
        deleteNode(temp.left, n);
    } else {
        deleteNode(temp.right, n);
    }
}
于 2014-02-06T10:14:09.767 回答
0

我知道这是一个非常古老的问题,但无论如何......接受的答案的实现取自c ++,因此指针的想法仍然存在,应该改变它,因为Java中没有指针。

因此,每次将节点更改为 null 或其他内容时,该节点的实例都会更改,但不会更改原始实例

此实现取自 coursera 算法课程之一。

public TreeNode deleteBSTNode(int value,TreeNode node)
{
    if(node==null)
    {
        System.out.println("the value " + value + " is not found");
        return null;
    }
    //delete
    if(node.data>value) node.left = deleteBSTNode(value,node.left);
    else if(node.data<value) node.right = deleteBSTNode(value,node.right);
    else{
        if(node.isLeaf())
            return null;
        if(node.right==null)
            return node.left;
        if(node.left==null)
            return node.right;

        TreeNode successor = findMax(node.left);
        int data = successor.data;
        deleteBSTNode(data, node.left);
        node.data = data;


    }
    return node;
}

节点之间的所有链接都使用递归的返回值。

于 2015-11-21T19:33:53.180 回答
0

对于深度优先后序遍历和移除,使用:

/*
 * 
 *  Remove uses
 *  depth-first Post-order traversal.
 *  
 * The Depth First Post-order traversal follows:
 * Left_Child -> Right-Child -> Node convention
 * 
 * Partial Logic was implemented from this source:
 * https://stackoverflow.com/questions/19870680/remove-method-binary-search-tree
 * by: sanjay
 */
@SuppressWarnings("unchecked")
public BinarySearchTreeVertex<E> remove(BinarySearchTreeVertex<E> rootParameter, E eParameter)  {
    BinarySearchTreeVertex<E> deleteNode = rootParameter;
    
    if ( deleteNode == null )   {
        return deleteNode;  }
    
    if ( deleteNode.compareTo(eParameter) == 1 )    {
        deleteNode.left_child = remove(deleteNode.left_child, eParameter);  }
    
    else if ( deleteNode.compareTo(eParameter) == -1 )  {
        deleteNode.right_child = remove(deleteNode.right_child, eParameter);    }
    
    else    {
        if ( deleteNode.left_child == null && deleteNode.right_child == null )  {
            deleteNode = null;
            }
        
        else if ( deleteNode.right_child == null )  {
            deleteNode = deleteNode.left_child; }
        
        else if ( deleteNode.left_child == null )   {
            deleteNode = deleteNode.right_child;    }
        
        else    {
            BinarySearchTreeVertex<E> interNode = findMaxLeftBranch( deleteNode.left_child );
            deleteNode.e = interNode.e;
            deleteNode.left_child = remove(deleteNode.left_child, interNode.e);
            }
    }   return deleteNode;  }   // End of remove(E e)

/*
 * Checking right branch for the swap value
 */
@SuppressWarnings("rawtypes")
public BinarySearchTreeVertex findMaxLeftBranch( BinarySearchTreeVertex vertexParameter )   {
    while (vertexParameter.right_child != null )    {
        vertexParameter = vertexParameter.right_child;  }
    return vertexParameter; }   // End of findMinRightBranch
于 2020-12-02T06:44:48.840 回答