Java 通过合并递归实现二叉树删除

Java 通过合并递归实现二叉树删除,java,recursion,binary-tree,Java,Recursion,Binary Tree,我已经实现了通过合并删除的迭代版本,但是我很难递归实现 这是我的迭代版本: public void deleteByMerging(T el) { BSTNode<T> tmp, node, p = root, prev = null; while (p != null && !p.el.equals(el)) { prev = p; if (el.compa

我已经实现了通过合并删除的迭代版本,但是我很难递归实现

这是我的迭代版本:

public void deleteByMerging(T el) {
    BSTNode<T> tmp, node, p = root, prev = null;
    while (p != null && !p.el.equals(el)) {  
         prev = p;                           
         if (el.compareTo(p.el) < 0)
              p = p.right;
         else p = p.left;
    }
    node = p;
    if (p != null && p.el.equals(el)) {
         if (node.right == null) 
              node = node.left;  
         else if (node.left == null) 
              node = node.right; 
         else {                  
              tmp = node.left;   
              while (tmp.right != null) 
                  tmp = tmp.right;      
              tmp.right =        
                  node.right;    

              node = node.left;  
         }
         if (p == root)
              root = node;
         else if (prev.left == p)
              prev.left = node;
         else prev.right = node; // 5.
    }
    else if (root != null)
         System.out.println("el " + el + " is not in the tree");
    else System.out.println("the tree is empty");
}
现在我需要以这种方式实现递归函数:

public void delete(T info) {
    root = delete(root, info);
}

public TreeNode<T> delete(TreeNode<T> node, T info) 
    {

    }

我对递归非常陌生,我不知道从哪里开始。

你的迭代版本,当然是指Adam Drozdek的

这应该起作用:

public void delete(T info) {
    root = delete (root.info);
}

public TreeNode<T> delete(TreeNode<T> node, T info) {

    // if this node is null, we have reached the end of the tree
    // so the node is not in the tree.
    if (node == null) {
        return node; // or handle as required

    // if this is not the node to delete;
    // recursively call this on the node's correct child
    else if (info.compareTo(node.info) <0) {
        node.left = delete(node.left, info);
        return node;
    } else {
        node.right = delete(node.right, info);
        return node;
    }

    // if this is the node to delete:
    else if (node.info.equals(info)) {
        // to delete it, we must return a sub-tree without it.

        if (node.left == null) 
            // this node is a leaf node, or
            // node.right contains only child.
            // either way, return node.right
            return node.right;

        if (node.right == null) 
            // node.left contains only child
            return node.left;

        // else node has 2 children, so delete by merging:
        // first, find its direct predecessor:
        TreeNode<T> tmp = node.left;
        while (tmp.right != null)
            tmp = tmp.right;
        // then append the node's right sub-tree
        // to its direct predecessor:
        tmp.right = node.right;
        // lastly, replace the node by its left sub-tree:
        return node.left;
    }
}
请注意,如果节点没有子节点,则第一个if检查将为true,因此将返回节点的右子节点null,从而删除该节点

为什么返回null会删除节点?因为,在上面讨论的遍历步骤中,我们将删除操作的结果分配给节点的子节点。请注意,上一个递归步骤中的节点是此步骤中节点的父节点,因为delete是在该节点的子节点上递归调用的。因此,在这里返回null将导致上一次调用将null分配给父级的子级,从而删除子级。基本上,任何时候我们返回除node以外的任何内容,我们都会用树中返回的内容替换当前节点

在第四种情况下,我们需要通过合并进行简单的删除。您可以通过将节点的右子树附加到其左子树中最右边的节点来实现这一点。首先,我们在左子树中找到最右边的节点,它是节点的直接前身:

最后,要用其左子树替换节点,我们只需返回node.left,因为这将用node.left替换节点,作为上一个递归调用中节点父节点的子节点

如果我的解释把你弄糊涂了,你可以试试。这更容易用纸上的图片解释,这就是为什么你应该在实践课上问我是的,我设置了这个prac,而不是这样:希望你在截止日期之前解决它

if (node.left == null)
    return node.right;
if (node.right == null)
    return node.left;
TreeNode<T> tmp = node.left;
while (tmp.right != null)
    tmp = tmp.right;
tmp.right = node.right;