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

这篇博客介绍了如何在二叉搜索树中进行最近公共祖先查找、插入操作和删除节点。235题通过递归或迭代方式找到两个节点间的中间节点作为最近公共祖先。701题讨论了如何遍历并插入新节点。450题中,删除节点涉及递归查找,根据节点情况决定返回其左子节点、右子节点或进行特殊处理来保持二叉搜索树性质。
摘要由CSDN通过智能技术生成

235. Lowest Common Ancestor of a Binary Search Tree

  • 思路
    • 递归
      • 从上往下遍历第一个在p,q之间的结点即所求
        • 如果是次近ancestor的话,不会再p,q之间
    • java
      
      
      class Solution {
          public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
              return helper(root, p,q);
          }
          
          
          private TreeNode helper(TreeNode root, TreeNode p, TreeNode q){
              if (root == null){
                  return root;
              }
              if (root.val > p.val && root.val >q.val){
                  TreeNode left = helper(root.left, p, q);
                  if (left != null){
                      return left;
                  }
              }
              if (root.val 
    • 迭代
      • java
        
        class Solution {
            public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
                return helper(root, p,q);
            }
            
            
            private TreeNode helper(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. Insert into a Binary Search Tree

 

  • 思路
    • 遍历找叶子节点
    • java
      class Solution {
          public TreeNode insertIntoBST(TreeNode root, int val) {
              if (root == null){
                  TreeNode node = new TreeNode(val);
                  return node;
              }
              
              if (val < root.val){
                  root.left = insertIntoBST(root.left, val);
              }
              
              if (val > root.val){
                  root.right = insertIntoBST(root.right, val);
              }
              return root;
          }
      }
      
      
    • 迭代法双指针
    • java
      class Solution {
          public TreeNode insertIntoBST(TreeNode root, int val) {
              TreeNode cur = root;
              TreeNode pre = root;
              int curVal = 0;
              if (root == null){
                  return new TreeNode(val);
              }
          
              while (cur != null){
                  if (val > cur.val){
                      pre = cur;
                      curVal = cur.val;
                      cur = cur.right;
                  }else if( val < cur.val){
                      pre = cur;
                      curVal = cur.val;
                      cur = cur.left;
                  }
              }
              if (val > curVal){
                  pre.right = new TreeNode (val);
                  return root;
              }
              
              pre.left = new TreeNode(val);
              return root;
          }
      }

450. Delete Node in a BST 

  • 思路
    • 递归
      • 递归找要删除的结点
        • 找不到,return null
        • 找到了
          • 节点为子节点
            • return null
          • 节点左空右非空,非空继位
            • return node.right
          • 节点左非空右空, 非空继位
            • return node.left
          • 左右都非空
            • 把左子树(node.left)放到右子树最左边的孩子上
            • return node.right
        • 这种做法,如果删除值为6的节点
      • 是把上图变成下图
      • java
        
        
        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){
                        return null;
                    }
                    //节点左非空右空,非空继位
                    else if (root.left != null && root.right == null){
                        return root.left;
                    }
                    //节点左空右非空,非空继位  
                    else if (root.right != null && root.left == null){
                        return root.right;
                    }
                    //左右都非空
                    else{
                      //右子树
                        TreeNode cur = root.right;
                      //找右子树最左边的孩子
                        while( cur.left != null){
                            cur =cur.left;
                        }
                      //把左子树接到最左边的孩子的左子树上
                        cur.left = root.left;
                        return root.right;
                    }
                    
                }
                
                if (key < root.val){
                    root.left =  deleteNode(root.left, key);
                }
                if ( key > root.val){
                    root.right = deleteNode(root.right, key);
                }
                
                return root;
            }
        }
        
        

       

       

    • 通用方法
    • 前序遍历
      • 先将目标值交换到其右子树的最左边的孩子
        • 然后再删掉最其右子树的最左边的孩子
        • 是把上图变成下图

         

         

    • java
      
      class Solution {
          public TreeNode deleteNode(TreeNode root, int key) {
              if (root == null){
                  return root;
              }
              if (root.val == key){
                  if (root.right == null ){
                      return root.left;
                  }
                  TreeNode cur = root.right;
                  while( cur.left != null){
                      cur = cur.left;
                  }
                  swap(root, cur);
                             
              }
              
              root.left = deleteNode(root.left, key);
              root.right = deleteNode(root.right, key);
              return root;
          }
          private void swap(TreeNode root, TreeNode cur ){
              int temp = root.val;
              root.val = cur.val;
              cur.val = temp;
          }  
      }
      
      
      

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值