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

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

思路:如果p的值大于当前节点的值,q的值小于当前结点的值,那么当前节点就是最近公共祖先。因为当前节点的左子树没有q,当前节点的右子树没有p;

因此,只需要判断p,q的值同时大于或者同时小于当前节点,进行遍历。

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL)return NULL;
        //p,q的值都小于当前节点的值,那么遍历左子树
        if(root->val > p->val && root->val > q->val){
            TreeNode* left = lowestCommonAncestor(root->left, p, q);
            if(left)return left;
        }
        //p,q的值都小于当前节点的值,那么遍历右子树
        if(root->val < q->val && root->val < p->val){
            TreeNode*right = lowestCommonAncestor(root->right, p, q);
            if(right)return right;
        }
        return root;
    }
};

迭代法

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL)return NULL;
        while(root != NULL){
            if(p->val < root->val && q->val < root->val){
                root = root->left;
            }
            else if(p->val > root->val && q->val > root->val){
                root = root->right;
            }
            else return root;
        }
        return NULL;
    }
};

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

递归法

          root->left 和 root->right 是连接要插入的节点node与二叉树的,node的返回由root->left 或root ->right接收。

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root == NULL){
            TreeNode* node = new TreeNode(val);
            return node;
        }
        if(root->val > val){
            root->left = insertIntoBST(root->left, val);
        }
       if(root->val < val){
           root->right = insertIntoBST(root->right, val);
       }
       return root;
    }
};

迭代法

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root == NULL){
            TreeNode* node = new TreeNode(val);
            return node;
        }
        TreeNode* parent = root; //记录父结点;
        TreeNode* cur = root; //记录当前节点
        //找到要插入节点的父结点
        while(cur){
            parent = cur; //很重要,是作为父结点的,一旦cur为空,就进不了循环了,此时插入节点的父结点就是parent
            if(cur->val > val)cur = cur->left;
            else cur = cur->right;
        }
        TreeNode* node = new TreeNode(val);
        //判断该节点插入左子树还是右子树
        if(parent->val > val){
            parent->left = node;
        }else{
            parent->right = node;
        }
        return root;
    }
};

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

分五种情况进行判断,在进行终止条件的判定中,就将五种判断逻辑分别写上。

后面再遍历过程中,要用左孩子或者右孩子接住返回值,这是将返回值进行安放。

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        //要删除的节点为空
        if(root == NULL)return NULL;
        //要删除的节点不为空
        if(root->val == key){
            //1.要删除的节点是叶子结点,左右子树都为空,令返回值为NULL,即上一层会接一个NULL
            if(root->left == NULL && root->right == NULL){
                delete root;
                return NULL;
            }
            //2.要删除的节点左子树不为空,右子树为空,返回该节点的左子树
            else if(root->left != NULL && root->right == NULL){
                auto retNode = root->left;
                delete root;
                return retNode;
            }
            //3.要删除节点的左子树为空,右子树不为空,返回该节点的右子树
            else if(root->left == NULL && root->right != NULL){
                auto retNode = root->right;
                delete root;
                return retNode;
            }
            //4.要删除节点的左右子树都不为空,将右子树保留,左子树接在右子树的左子树上
            else {
                TreeNode* cur = root->right;
                while(cur->left){
                    cur = cur->left;  //找到左子树的叶子节点
                }
                cur->left = root->left;
                TreeNode* temp = root; //保存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;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值