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

今天是二叉树相关算法学习的第七天。主要的学习内容有:二叉搜索树的最近祖先,以及二叉搜索树的插入和删除操作。

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

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

我刚拿到这个题,就直接用一般二叉树查找公共祖先的方法解决了问题。具体代码实现如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

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

 当具备二叉搜索树这一性质后,可以更简单的查找两节点的公共祖先。因为二叉搜索树是具备有序性的,所以在遍历过程中,第一次出现节点的值在p节点和q节点值的中间时,该节点就是p节点和q节点的公共节点。按照前序遍历就可以。具体代码实现如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution {
public:
TreeNode* result=new TreeNode();
bool isfirst=0;
    void order(TreeNode* root,TreeNode* p,TreeNode* q)
    {
     if(root==NULL) return;
     int max=-10010,min=-10010;
     if(p->val>=q->val) max=p->val,min=q->val;
     else max=q->val,min=p->val;
      if(root->val>=min&&root->val<=max) 
     {
        if(isfirst==0)
        {
            isfirst=1;
            result=root;
        }
        
     }
     lowestCommonAncestor(root->left,p,q);
     lowestCommonAncestor(root->right,p,q);
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    order(root,p,q);
    return result;
    }
};

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

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

这个题感觉比较简单,按照二叉搜索树的性质进行插入就可以。对于终止条件,如果插入的值大于根节点就往右走,小于根节点就往左走,遇到空值就进行插入即可。具体代码实现如下:
 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void order(TreeNode* root,int val)
    {
        if(root==NULL) return;
        if(val>root->val&&root->right==NULL)
        {
            TreeNode* node=new TreeNode(val);
            root->right=node;
        }
        if(val<root->val&&root->left==NULL)
        {
            TreeNode* node=new TreeNode(val);
            root->left=node;
        }
        if(val>root->val)order(root->right,val);
        else order(root->left,val);
    }
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root==NULL)
        {
             TreeNode* node=new TreeNode(val);
            return node;
        }
        order(root,val);
        return root;
    }
};

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

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

这个题就比较复杂了,是看了题解做出来的,尤其是第五种情况的处理确实有点复杂。当要删除二叉搜索树里的某个节点时,涉及到五种情况:

1.删除节点本身为NULL,返回NULL

2.删除节点的左右节点都为空,直接返回NULL

3.删除节点的左节点为空,右节点不为空,返回该节点的右子树

4.删除节点的右节点为空,左节点不为空,返回该节点的左子树

5.删除节点的左右节点都不为空,首先查找该节点右子树的最左侧的值,将删除节点的左子树插入到删除节点右子树的最左节点的左子树。因为删除节点右子树的最左节点是大于删除节点左子树的最小值。然后返回删除节点的右子树。
具体代码实现如下:
 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (root == NULL)
            return NULL;
        if (root->val == key) {
            if (root->left == NULL && root->right == NULL) {
                delete root;
                return NULL;
            }
            if (root->left != NULL && root->right == NULL) {
                TreeNode* node = root->left;
                delete root;
                return node;
            }
            if (root->left == NULL && root->right != NULL) {
                TreeNode* node = root->right;
                delete root;
                return node;
            }
            if (root->left != NULL && root->right != NULL) {
                TreeNode* cur = root->right;
                while (cur->left != NULL)
                    cur = cur->left;
                cur->left = root->left;
                TreeNode* temp = root->right;
                delete root;
                return temp;
            }
        }
        if (key < root->val)
            root->left = deleteNode(root->left, key);
        if (key > root->val)
            root->right = deleteNode(root->right, key);
        return root;
    }
};

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14训练营,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15的讨论,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16的讨论,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值