夸父追日:第六章 二叉树part07

今日收获:二叉搜索树的最近公共祖先,插入操作,删除节点

1. 二叉搜索树的最近公共祖先

题目链接:235. - 力扣(LeetCode)

思路:和求二叉树的最近公共祖先不同,这道题可以充分利用二叉搜索树的特性。根据root和两个节点的值判断,如果都大于两个节点,则结果在root左区间,反之亦然;如果root在区间中,则结果是root。

方法:

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 结果在root的左区间
        if (root.val>p.val&&root.val>q.val){
            return lowestCommonAncestor(root.left,p,q);
        }

        // 结果在root的右区间
        if (root.val<p.val&&root.val<q.val){
            return lowestCommonAncestor(root.right,p,q);
        }
        
        // root在两个值中间
        return root;
    }
}

总结:二叉搜索树中,在两个节点值区间的节点一定是最近公共祖先

2. 二叉搜索树的插入操作

题目链接:701. - 力扣(LeetCode)

思路:根据当前节点的值和插入值来判断插入位置。如果当前节点的值大于插入值,说明应该插入当前节点的左边。如果左子树为空,则插入左节点;否则递归调用方法,插入当前节点的左子树

方法:

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if (root==null){
            return new TreeNode(val);
        }

        // 插入左边
        if (root.val>val){
            if (root.left!=null){
                insertIntoBST(root.left,val);
            }else {
                root.left=new TreeNode(val);
            }
        }

        // 插入右边
        if (root.val<val){
            if (root.right!=null){
                insertIntoBST(root.right,val);
            }else {
                root.right=new TreeNode(val);
            }
        }

        return root;
    }
}

3. 删除二叉搜索树中的节点

题目链接:450. - 力扣(LeetCode)

思路:如果删除当前节点,根据当前节点是否有左右孩子做不同处理,如果左右孩子都有,则当前节点的左孩子变成右孩子最左边节点的左孩;否则比较当前节点的值和目标值,分别交给左右子树处理

方法:

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root==null){
            return null;
        }

        // 删除当前节点
        if (root.val==key){
            // 叶子节点
            if (root.left==null&&root.right==null){
                return null;
            }
            // 只有左孩子
            if (root.right==null){
                return root.left;
            }
            // 只有右孩子
            if (root.left==null){
                return root.right;
            }
            // 左右孩子都有
            // 根节点的左孩子变成右孩子最左边节点的左孩子
            TreeNode maxleft=root.right;
            while (maxleft.left!=null){
                maxleft=maxleft.left;
            }
            maxleft.left=root.left;
            return root.right;
        }

        // 交给左右子树
        if (root.val>key){
            root.left=deleteNode(root.left,key);
        }

        if (root.val<key){
            root.right=deleteNode(root.right,key);
        }

        return root;
    }
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值