代码随想录训练营第22天|235. 二叉搜索树的最近公共祖先,701.二叉搜索树中的插入操作,450.删除二叉搜索树中的节点

代码随想录训练营第22天|235. 二叉搜索树的最近公共祖先,701.二叉搜索树中的插入操作,450.删除二叉搜索树中的节点


)

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

文章

代码随想录|0235.二叉搜索树的最近公共祖先

思路

从根节点出发
如果当前节点值介于两目标节点之间,说明目标节点分别在当前节点的左右子树中,则当前节点必然是最近公共祖先
若当前节点小于目标节点值则目标节点在右子树,下一步访问右孩子
若当前节点大于目标节点值则目标节点在左子树,下一步访问左孩子
考虑特殊情况,,目标节点中一个是另一个的祖先,则可以用闭区间确定当前节点而没有例外

代码

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        int upper, lower;
        upper = p.val > q.val ? p.val : q.val;
        lower = p.val > q.val ? q.val : p.val;
        TreeNode node = root;
        while(node.val < lower || node.val > upper) {
            if (node.val < lower) {
                node = node.right;
            } else {
                node = node.left;
            }
        }
        return node;
    }
}

701.二叉搜索树中的插入操作

文章

代码随想录|0701.二叉搜索树中的插入操作

思路

最简单思路是找到一个可插入的位置,插入新节点

代码

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if (root == null) {
            return new TreeNode(val);
        }
        TreeNode node = root;
        while (true) {
            if (node.val > val) {
                if (node.left == null) {
                    node.left = new TreeNode(val);
                    return root;
                } else {
                    node = node.left;
                    continue;
                }
            } else {
                if (node.right == null) {
                    node.right = new TreeNode(val);
                    return root;
                } else {
                    node = node.right;
                    continue;
                }
            }
        }
        // return root;
    }
}

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

文章

代码随想录|0450.删除二叉搜索树中的节点

思路

找到删除的目标节点,维护目标节点的父节点,标记目标节点是其父节点的左或右孩子
为了应对删除根节点的情况,建立虚节点,使根节点成为其的一个孩子
找到删除的目标节点后,将目标节点的一个非空孩子插入目标节点的原位置,可以通过父节点和左右标记确定,另一个孩子插入前一个孩子的末端,如果插入父节点的是大孩子,则小孩子插入大孩子的最左,如果插入父节点的是小孩子,则大孩子插入小孩子的右端。
最后返回虚节点的孩子

代码

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) {
            return null;
        }
        TreeNode pre;
        TreeNode dummy = new TreeNode(-100001);
        dummy.right = root;
        pre = dummy;
        TreeNode node = root;
        int child = 1;
        while (node != null && node.val != key) {
            pre = node;
            if (node.val > key) {
                node = node.left;
                child = 0;
            } else {
                node = node.right;
                child = 1;
            }
        }
        if (node == null) {
            return root;
        }
        TreeNode lower, upper;
        lower = node.left;
        upper = node.right;
        if (child == 0) {
            if (upper != null) {
                pre.left = upper;
                if (lower != null) {
                    while (upper.left != null) {
                        upper = upper.left;
                    }
                    upper.left = lower;
                }
            } else {
                pre.left = lower;
            }
        }
        else if (child == 1) {
            if (lower != null) {
                pre.right = lower;
                if (upper != null) {
                    while (lower.right != null) {
                        lower = lower.right;
                    }
                    lower.right = upper;
                }
            } else {
                pre.right = upper;
            }
        }
        return dummy.right;
    }
}

总结

总体上比较简单
删除操作比较复杂
虚节点这种做法原来不止适用于链表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值