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

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

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

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL)
        return root;
        if(root->val > p->val && root->val > q->val)
        {
            TreeNode* left = lowestCommonAncestor(root->left,p,q);
            if(left != NULL)
            return left;
        }//左子树中寻找
        else if(root->val < p->val && root->val < q->val)
        {
            TreeNode* right = lowestCommonAncestor(root->right,p,q);
            if(right != NULL)
            return right;
        }//右子树中寻找
        return root;
    }
};

思路: 利用二叉搜索树的特性(节点值一定大于左子树的值同时小于右子树的值),当节点值大于两个目标节点的值时在左子树中进行寻找,并返回寻找到的节点;当节点值小于两个目标节点的值时在右子树中进行寻找,并返回寻找到的节点。最后返回寻找到的根节点即可。

小结:节点值在目标节点值之间时,则该节点一定是目标节点的最近公共祖先


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

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

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root == NULL)//root为空寻找到叶子节点位置
        {
            TreeNode* node = new TreeNode(val);
            return node;//设定新节点并将其返回
        }
        if(val > root->val)//插入值大于节点值时在右子树插入
        root->right = insertIntoBST(root->right,val);//将节点的右子树设定为新节点
        if(val < root->val)//插入值大于节点值时在左子树插入
        root->left = insertIntoBST(root->left,val);//将节点的左子树设定为新节点
        return root;//返回根节点
    }
};

思路: 我们规定,在二叉树的叶子节点插入新节点(这样不会改变树的结构)。遍历终止条件即为:寻找到空节点,之后我们设定一个新节点,并将其返回。单层逻辑为对插入值与节点值进行比较,之后寻找到对应的叶子节点;此时我们将新节点返回给叶子节点的左右子树,完成插入操作。最后返回根节点即可。

小结:在进行遍历时,我们并没有改变root这个根节点,而是通过根节点的左右子树进行遍历,故返回时直接但返回root即可。


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

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

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        //确定终止条件以及返回值
        if(root == NULL)
        return NULL;//没有找到要删除的节点,返回空
        if(key == root->val)//找到要删除的节点
        {
            if(root->right == NULL && root->left == NULL)//情况一,节点左右子树均为空(叶子节点)
           {
               delete root;
               return NULL;//直接删除节点,返回空
           }
           else if(root->right != NULL && root->left == NULL)//情况二,节点右子树不为空,左子树为空
           {
               TreeNode* node = root->right;//保存右子树
               delete root;//删除节点
               return node;//返回右子树
           }
           else if(root->left != NULL && root->right == NULL)//情况三,节点左子树不为空,右子树为空
           {
               TreeNode* node = root->left;//保存左子树
               delete root;//删除节点
               return node;//返回左子树
           }
           else//情况四,节点左右子树均不为空
           {
               TreeNode* cur = root->right;//设定新节点为右子树
               while(cur->left != NULL)//找到右子树最左叶子节点
               {
                   cur = cur->left; 
               }
               cur->left = root->left;//将最左叶子节点的左子树设定为原节点的左子树
               TreeNode* node = root->right;//保存右子树
               delete root;//删除节点
               return node;//返回右子树
           }
        }
        if(key > root->val)
        root->right = deleteNode(root->right,key);
        else if(key < root->val)
        root->left = deleteNode(root->left,key);
        return root;
    }
};

思路:在删除节点时,我们需要将新的子节点给目标节点的父节点,故遍历返回值为新节点。在寻找节点时会出先两种大情况:寻找到需要删除的节点,没有寻找到需要删除的节点。没有寻找到要删除的节点时新节点为空,直接返回即可。而寻找到要删除的节点时,共有四种情况,对每一种情况进行对应操作并返回新节点即可。

小结: 找到目标节点的情况四中,也可以先将右子树移至左子树的叶子节点,之后将左子树返回。

你可能感兴趣的:(leetcode,算法,c++,数据结构)