day 22 235. 二叉搜索树的最近公共祖先;450. 删除二叉搜索树中的节点;701.二叉搜索树中的插入操作

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

思路:没有前中后遍历顺序,因为不需要处理中间节点

因为是有序树,所有 如果 中间节点是 q 和 p 的公共祖先,那么 中节点的数组 一定是在 [p, q]区间的。即 中节点 > p && 中节点 < q 或者 中节点 > q && 中节点 < p
1.遇到 cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是q 和 p的公共祖先,但不一定是最近的公共祖先
在这里插入图片描述如果从节点5向左遍历,向右遍历就会出错,因为3和8也是[1,9]区间的,记录第一次出现在区间的值是最近公共祖先

递归

1.确认递归返回值和参数

 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)

2.确认终止条件

if(root==NULL)return NULL;

3.确认单层递归逻辑

寻找区间[p->val, q->val](注意这里是左闭又闭)

那么如果 cur->val 大于 p->val,同时 cur->val 大于q->val,那么就应该向左遍历(说明目标区间在左子树上)

4.完整代码

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

迭代

class Solution {
public://中左右遍历
    
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            while(root!=NULL)
            {  
                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 root;
    }        
};

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

思路:只要按照二叉搜索树的规则去遍历,遇到空节点就插入节点就可以了

递归

1.确认递归返回值和参数

TreeNode* insertIntoBST(TreeNode* root, int val)

2.确认终止条件:终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。

   if(root == nullptr) 
             {
                 TreeNode* newnode=new TreeNode(val);
                 return newnode;
             }

3.确认单层递归逻辑:根据插入元素的数值,决定递归方向

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

完整代码

class Solution {
public:
          TreeNode* insertIntoBST(TreeNode* root, int val) {
             if(root == nullptr) 
             {
                 TreeNode* newnode=new TreeNode(val);
                 return newnode;
             }
             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==nullptr)
        {
            TreeNode*cur=new TreeNode(val);
            return cur;
        }
         TreeNode* cur=root;
        while(cur!=nullptr)
        {
            if(cur->val>val) 
            {
                if(cur->left)cur=cur->left;
                else{ cur->left=new TreeNode(val);
                break;}
                
            }
            if(cur->val<val)
             {
                if(cur->right)cur=cur->right;
                else{
                 cur->right=new TreeNode(val);
                 break;}
            }
        }
         return root;
         }
};

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

递归思路复杂性高,因为涉及到树的结构改变

1.没找到删除的点

if(root==nullptr)return nullptr;

2删除的点为叶子节点,即左右子树都为空,删除叶子节点

if(root->left==nullptr&&root->right==nullptr)//左右都为空
            {
                return nullptr;
            }

3.删除的点的左子树为空,右子树不为空

if(root->left==nullptr&&root->right!=nullptr)//左为空,右不为空
            {
                return root->right;
            }

4.删除的点的左子树不为空,右子树为空

if(root->left!=nullptr&&root->right==nullptr)//左不为空,右为空
            {
                return root->left;
            }

5.删除的点的左子树不为空,右子树不为空:例如删除7,将7的左子树,放在7右子树上比7大一点最小的数左子树上,再删除7

 else
            {
                TreeNode* cur=root;
                while(cur->left!=nullptr)//找到cur最左的子树,
                {
                    cur=cur->left;
                }
                    cur->left=root->left;//将cur的左子树指向root 的左子树
                    return cur->right;//删除当前节点
            }

在这里插入图片描述在这里插入图片描述

1.确认递归返回值和参数TreeNode* deleteNode(TreeNode* root, int key)

2.确认终止条件:遇到空返回,其实这也说明没找到删除的节点,遍历到空节点直接返回了if (root == nullptr) return root;

3.确认单层递归逻辑:二叉搜索树中删除节点遇到了五种情况。

4.完整代码

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)//左右都为空
            {
                return nullptr;
            }
            if(root->left!=nullptr&&root->right==nullptr)//左不为空,右为空
            {
                return root->left;
            }
            if(root->left==nullptr&&root->right!=nullptr)//左为空,右不为空
            {
                return root->right;
            }
             if(root->left!=nullptr&&root->right!=nullptr)
            {
                TreeNode* cur=root->right;//cur指向root的右子树
                while(cur->left!=nullptr)//找到cur最左的子树,
                {
                    cur=cur->left;
                }
                    cur->left=root->left;//将cur的左子树指向root 的左子树  
                    return root->right;//删除当前节点
            }
        } 
        if(root->val>key) root->left=deleteNode(root->left,key);
        if(root->val<key) root->right=deleteNode(root->right,key);
    return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值