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

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

题目链接 235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

从数学角度来说,本体应用了搜索二叉树的特性:所有节点唯一且所有左侧节点小于右侧节点,这样当我们确定了所给的两个节点(p,q)时,只需要找到第一个节点对应的值处在(p,q)区间的节点就是我们要找的节点。这样并不会出现找的节点不够深,因为它上一层的节点必定大于或小于这一整个枝的节点,不满足条件。据此可以确定单层递归的逻辑:如果当前节点值比q,p都大,向左递归,比p,q都小,向右递归。

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

同时每一层返回下一层递归回返回的节点(直到出现符合的节点,返回其地址),因此返回参数设置为

TreeNode*traversal(TreeNode* root,TreeNode* p,TreeNode* q){

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

题目链接 701. 二叉搜索树中的插入操作 - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 同样的二叉搜索树思路,若插入的值大于当前值向右递归,小于当前值,向左递归

if(root->val>val){
            traversal(root->left,val);

        }
if(root->val<val){
            traversal(root->right,val);
        }

每次不需要返回值,故函数类型为void

void traversal(TreeNode* root,int val){

同时定义一个全局变量parent用来定义上一层的节点,这样每到一层,先判断,若为空节点,则开始在上一层节点后安插,若不是,则将当层节点填入parent开始下一层。

TreeNode* parent;
    void traversal(TreeNode* root,int val){
        if(root==NULL){
            TreeNode* cur=new TreeNode(val);
            if(parent->val>val){
                parent->left=cur;
            }
            else{
                parent->right=cur;
            }
            return;
        }

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

题目链接 450. 删除二叉搜索树中的节点 - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 删除二叉搜索树的节点,总的来说,我觉得有两个难点:首先便是若是被删除的节点有左右子系节点应该怎么办,还有就是函数返回值问题:最终肯定要返回root,那递归时每一次返回什么呢?

首先第一点,当前节点删除后,右子树补上,将左子树整个剪下来,贴到右子树最左侧节点上。

 

f(root->val==key){
            if(root->left==NULL&&root->right==NULL){
                delete root;
                return NULL;
            }
            else if(root->left==NULL&&root->right!=NULL){
                auto temp=root->right;
                delete root;
                return temp;
            }
            else if(root->left!=NULL&&root->right==NULL){
                auto temp=root->left;
                delete root;
                return temp;
            }
            else{
                auto rightLeft=root->right;
                while(rightLeft->left!=NULL){
                    rightLeft=rightLeft->left;
                }
                rightLeft->left=root->left;
                auto temp=root->right;
                delete root;
                return temp;



            }

第二点就是每一次将当前节点的左右指针指向递归后的返回值,这样在更新整个二叉树的时候就会每一个节点重新定义左右子枝,在最后返回root就可以了。

f(root->val>key)root->left=deleteNode(root->left,key);
        if(root->val<key)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、付费专栏及课程。

余额充值