美文网首页
二叉搜索树的插入和删除

二叉搜索树的插入和删除

作者: lkuuuuuun | 来源:发表于2019-08-06 16:13 被阅读0次

    有了前文对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;
            }
        }
    

    相关文章

      网友评论

          本文标题:二叉搜索树的插入和删除

          本文链接:https://www.haomeiwen.com/subject/zlhwdctx.html