5-7 删除一个节点:步骤1-删除最大值,最小值

把握下面的这个最基本且简单的性质:
最小值:从根节点开始,不停地沿着左边节点的方向找,直到再也没有左节点为止;
最大值:从根节点开始,不停地沿着右边节点的方向找,直到再也没有右节点为止。

试着用非递归的方式实现一下。

下面的逻辑,虽然简单,但是有陷阱,自己要关注一下细节。

删除最小值的节点
关键把握一点:
如果最小值的节点没有右孩子,很好办,直接删除,如果最小值的节点有右孩子,让右孩子代替自己(自己试着在图上画出这个过程,就很好理解了)。

/**
 * 从二分搜索树中删除最小 key 所在的节点
 */
public void removeMin() {
    if (root != null) {
        root = removeMin(root);
    }
}

/**
 * 删除以 node 为根的二分搜索树中的最小的节点
 * 返回删除节点后新的二分搜索树的根
 * @param node
 * @return
 */
private Node removeMin(Node node) {
    if (node.left == null) {
        // 就是删除这个节点 node
        Node rightNode = node.right;
        node.right = null;
        count--;
        return rightNode;
    }
    node.left = removeMin(node.left);
    return node;
}

代码:node.left = removeMin(node.left); 是很重要的(这里可以画一张图辅助我们理解)。

删除最大值的节点

/**
 * 使用递归的方式删除二分搜索树最大 key 所在的节点
 */
public void removeMax() {
    if (root != null) {
        root = removeMax(root);
    }
}

/**
 * 删除以 node 为根的二分搜索树的 key 最大的那个节点
 * 返回删除了节点以后的新的二分搜索树的根
 *
 * @param node
 * @return
 */
public Node removeMax(Node node) {
    if (node.right == null) {
        Node leftNode = node.left;
        node.left = null;
        count--;
        // 返回删除了节点以后的新的二分搜索树的根
        return leftNode;
    } else { // node.right != null
        node.right = removeMax(node.right);
        return node.right;
    }
}

说明:
1、以上两个方法还可以使用循环的方式实现,可以尝试一下
2、以上的这两个删除的方法为我们删除任意一个节点做好的铺垫,请引起重视。

猜你喜欢

转载自blog.csdn.net/lw_power/article/details/78007645