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

day22 2023/02/22

一、二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

思路如下

利用回溯从底向上搜索,遇到一个节点的左子树里有p,右子树里有q,那么当前节点就是最近公共祖先。

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

代码如下

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)
         return left;
     }
     if(root->valval&&root->valval)
     {
         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||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 root;
    if(left==NULL&&right!=NULL) return right;
    if(left!=NULL&&right==NULL) return left;
    else return NULL;
    }
};

 

二、二叉搜索树中的插入操作

给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据保证,新值和原始二叉搜索树中的任意节点值都不同。

思路如下:

表示此题比较简单,学数据结构的时候就写过了

代码如下

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

     if(val>root->val)
        root->right=insertIntoBST(root->right,val);
     else if(valval)
        root->left=insertIntoBST(root->left,val);
      return root;
    }
};

三、删除二叉搜索树中的节点

思路如下

此题比较相对于上题来说比较复杂,需要复习巩固

删除节点的时候有以下五种情况:

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了
  • 找到删除的节点
    • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
    • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
    • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
    • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。

代码如下

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
      if(root==NULL) return root;
      
      if(root->val==key)
      {
          //如果左节点和右节点都为空,则直接删除
          if(root->left==NULL&&root->right==NULL)
          {
              delete root;
              return NULL;
          }
          //如果左节点为空但是右节点不为空
          else if(root->left==NULL&&root->right!=NULL)
          {
              TreeNode* cur=root->right;
              delete root;
              return cur;
          }
          //如果左节点不为空但是右节点为空
          else if(root->left!=NULL&&root->right==NULL)
          {
              TreeNode* cur=root->left;
              delete root;
              return cur;
          }
          //如果左节点和右节点均不为空
          else
          {
              //先找到该节点右子树的最左边的节点
              TreeNode* cur=root->right;
              while(cur->left!=NULL)
              {
                  cur=cur->left;
              }
              cur->left=root->left;
              TreeNode* tmp=root;
              root=root->right;
              delete tmp;
              return root;
          }

      }
      if(root->val>key)
      {
           root->left=deleteNode(root->left,key);
      }
      if(root->valright=deleteNode(root->right,key);
      }
      return root;
    }
};

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