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

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

题目链接:235. 二叉搜索树的最近公共祖先

此题比上一题二叉树的的最近公共祖先容易一些,可以利用二叉搜索树的性质,当p和q在根节点左侧,遍历左子树,都在右侧遍历右子树,在两侧则根节点就是最近公共祖先。

迭代法

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == NULL) return root;
        if (p->val < root->val && q->val < root->val) {
            return lowestCommonAncestor(root->left, p, q);
        } 
        if (p->val > root->val && q->val > root->val) {
          return lowestCommonAncestor(root->right, p, q);
        }
      return root; //在两侧的情况
    }
};

迭代法

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        while (root) {
            if (root->val > p->val && root->val > q->val) { //都在左侧
                root = root->left;
            } else if (root->val < p->val && root->val < q->val) {//都在右侧
                root = root->right;
            } else return root; //在两侧
        }
        return NULL;
    }
};

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

题目链接:701. 二叉搜索树中的插入操作

看似很麻烦,但是在二叉搜索树中插入都可以转换为直接在叶子节点插入,所以不需要改动二叉树的结构。

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if (root == nullptr) { //此节点就是要插入的位置
            TreeNode* node = new TreeNode(val);
            return node;
        }

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

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

题目链接:450. 删除二叉搜索树中的节点

此题要删除二叉树中的节点,所以大多情况需要改动树的结构
有以下几种情况:

  • 树中无要删除的节点,此时直接返回
  • 树中有要删除的节点
    • 要删除的节点是叶子结点,此时直接返回一个空
    • 要删除的节点左不为空,右为空,让他的父节点直接指向左
    • 要删除的节点左为空,右不为空,让他的父节点直接指向右
    • 要删除的节点左右都不为空,此时最复杂,可以让他的右节点作为此根节点,然后其左子树接在右子树的最左边子树

在这里插入图片描述

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (root == nullptr) return nullptr;
        if (root->val == key) {
            if (root->left == nullptr && root->right ==nullptr) {
                delete root;
                return nullptr;
            } else if (root->left && !root->right) {
                TreeNode* node = root->left;
                delete root;
                return node;
            } else if (!root->left && root->right) {
                TreeNode* node = root->right;
                delete root;
                return node;
            } else {
                TreeNode* cur = root->right;
                while (cur->left) {//让cur不断指向左边,保证最小
                    cur = cur->left;
                }
                cur->left = root->left;
                TreeNode* temp = root;
                root = root->right;
                delete temp;
                return root;
            }
        }
		//利用搜索树的性质
        if (key < root->val) root->left = deleteNode(root->left, key);
        if (key > root->val) root->right = deleteNode(root->right, key);
        return root;
    }
};

注意: c++不要忘记手动释放删除的节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值