第22天-代码随想录刷题训练-第六章● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

文章介绍了如何在二叉搜索树中找到最近公共祖先,以及如何进行插入和删除操作。对于最近公共祖先,可以通过从上往下遍历二叉搜索树找到位于给定节点值区间的节点。插入操作通过前序遍历确保保持BST性质。删除节点时,需考虑四种情况并调整树结构。
摘要由CSDN通过智能技术生成

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

- LeetCode链接

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

  • 二插搜索树, 从上往下遍历的话,当遇到根节点的值在区间 [p, q] 内,则一定是最近公共祖先(注意这里是开区间)
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        // 二叉搜索树: 最近父节点一定是在 [p q] 区间内的
        // 因此从上往下遍历,只要遇到在这个区间内的,就一定是最近公共祖先
        if(root == NULL) return root;

        if((root->val >= p->val && root->val <= q->val) || (root->val <= p->val && root->val >= q->val)){
            return root;
        }
        TreeNode* leftNode = lowestCommonAncestor(root->left, p, q);
        TreeNode* rightNode = lowestCommonAncestor(root->right, p, q);

        return leftNode != NULL ? leftNode : rightNode;
    }
};

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

- LeetCode链接

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

  • 判断左右子节点的版本
 */
class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root == NULL){
            TreeNode* node = new TreeNode(val);
            return node;
        }

        // 前序遍历
        if(val < root->val){ 
            if(root->left == NULL){
                TreeNode* node = new TreeNode(val);
                root->left = node;
                return root;
            }       
            insertIntoBST(root->left, val);
        }else{
            if(root->right == NULL){
                TreeNode* node = new TreeNode(val);
                root->right = node;
                return root;
            } 
            insertIntoBST(root->right, val);
        }

        return root;
    }
};
  • 判断当前节点的版本
class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root == NULL) return new TreeNode(val);

        if(root->val > val) root->left = insertIntoBST(root->left, val);
        if(root->val < val) root->right = insertIntoBST(root->right, val);
        return root;
    }
};

3.删除二叉树中的节点

- LeetCode链接

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;
如果找到了,删除它。

class Solution {
public:
    // 删除当前节点n(如果有左右子节点则称为p和q)
    // 1. 如果没有左右节点,直接删除
    // 2. 左右节点都不为空,将q代替n,q旧的左子树需要移动到 p的右子树上, q的left需要变为p
 
    // 3. 如果只有左节点没有右边节点: 直接将p代替n
    // 4. 只有右节点没有左节点: 直接将q代替n

    TreeNode* deleteNode(TreeNode* root, int key) {
        if(root == NULL) return root;

        // 前序遍历
        if(root->val == key){
            // 如果没有左右节点
            if(root->left == NULL && root->right == NULL) return NULL;

            // 如果只有左节点, 没有右节点, 直接返回root->left, 代替以前的root
            else if(root->left != NULL && root->right == NULL){
                return root->left;
            }
            // 如果只有右节点,没有左节点, 直接返回root->right 代替以前的root
            else if(root->left == NULL && root->right != NULL){
                return root->right;
            }
            // 如果左右节点都存在
            else if(root->left != NULL && root->right != NULL){
                // root->right->right 不变

                // 将root—>right->left 移动到 root->left->right上
                TreeNode* cur = root->left;
                while(cur->right != NULL){
                    cur = cur->right;
                }
                cur->right = root->right->left;
                // 将root->right->left清除
                root->right->left = root->left;

                return root->right;     // 还需要进行后续的操作
            }
        }
        root->left =  deleteNode(root->left, key);
        root->right =  deleteNode(root->right, key);

        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值