二叉搜索树的插入和删除

2019-08-06  本文已影响0人  lkuuuuuun

有了前文对BST的前驱后驱理解的基础,还不理解的小伙伴戳这里二叉搜索树的前驱、后驱.我们便可以学习BST的插入和删除操作

插入节点:
需要从根结点开始查找待插入节点位置,找到位置后插入即可,如若在查找过程碰到相同元素 插入失败
代码如下:

    // 二叉搜索树插入节点
    public static boolean insert(TreeNode root, TreeNode node) {
        TreeNode tree = root;
        TreeNode p = null;
        // 寻找合适的插入位子 p节点即为插入节点的父节点
        while (tree != null) {
            p = tree;
            if (tree.val > node.val) { // 小于比较节点 放入比较节点的左子树
                tree = tree.left;
            } else if (tree.val < node.val) { // 大于比较节点 放入比较节点的右子树
                tree = tree.right;
            } else {
                return false; // 二叉搜索树中已有相同元素节点 插入失败
            }
        }
        node.parent = p;
        if (p == null) { // root 为null node为根节点
            root = node;
        } else if (p.val > node.val) {
            p.left = node;
        } else {
            p.right = node;
        }
        return true;
    }

删除节点
删除节点可以分以下3个情形:
1.待删除节点没有左,右孩子(即为叶子节点),直接删除
2.待删除节点只有1个子节点,将待删除节点的父节点设置为该子节点的父节点,
3.待删除节点有2个子节点,可以通过寻找待删除节点的后驱节点,来转化为以上2种情况,具体操作如下
这时我们并不直接删除待删除节点,而是删除待删节点的后驱节点,找到后驱节点后,将待删除节点的父节点设置为后驱节点子节点的父节点,同时将后驱节点的val设置到待删节点上,此时便完成删除操作
如下图:

待删节点有2个子节点情况
Java代码实现如下:
    // 二叉搜索树删除节点
    public static void delete(TreeNode root, TreeNode node) {
        TreeNode deleteNode = null;
        if (node.left == null || node.right == null) {
            deleteNode = node;
        } else {
            // 后驱节点即为删除节点 (后驱节点 必然没有左子节点)
            deleteNode = postNode(node);
        }

        // 删除节点必然不会超过一个子节点 要么1个 要么没有子节点
        TreeNode child = deleteNode.left == null ? deleteNode.right : deleteNode.left;

        if (child != null) {
            child.parent = deleteNode.parent;
        }
        if (deleteNode.parent == null) // 待删除节点没有父节点删除为节点后子孩子就是根节点了
            root = child;
        else if (deleteNode == deleteNode.parent.left) {
            deleteNode.parent.left = child;
        } else
            deleteNode.parent.right = child;

        // 如果删除节点是后驱节点 则需把删除的后驱节点的值设置在node上
        if (node != deleteNode) {
            node.val = deleteNode.val;
        }
    }
上一篇下一篇

猜你喜欢

热点阅读