代码训练营Day20 | 235. 二叉搜索树的最近公共祖先 | 701.二叉搜索树中的插入操作 | 450.删除二叉搜索树中的节点

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

1. 遍历根节点的时候,当前遍历的节点比p跟q都大的话,公共祖先在当前遍历节点的左子树里

2. 如果p跟q比当前遍历的节点都小的话,说明在右子树中

3. 如果当前遍历的值在p跟q之间,那么这个就是公共节点

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        def traversal(cur,p,q):
            # recursion stop condition
            if cur == None:
                # the node is empty,it won't have common ancestor
                return cur

            # single recursion logic
            if(cur.val > p.val and cur.val > q.val):
                # we need to search left sub tree
                left = traversal(cur.left,p,q)
                # check if we find node or not
                if(left is not None):
                    # we find common ancestor 
                    return left
            
            # iterate right
            elif(cur.val < p.val and cur.val < q.val):
                right = traversal(cur.right,p,q)
                # check we find ancestor or not
                if(right is not None):
                    return right
            
            else:
                # current node val is between p and q, mean's it must be common ancestor
                return cur
            
        return traversal(root,p,q)
        

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

1. 递归停止条件:当传递的节点为空时,我们就可以插入新节点了,创建一个值为val的节点并return

2. 利用二叉树特性,当前值大于题目给的val说明要搜索左子树,我们对左边进行递归

3. 如果当前值小于val,则递归右边,用root.right/root.left去接受值

4. 最后返回root

# Definition for a binary tree node.
class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution(object):
    def insertIntoBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        
        def traversal(node,val):
            # recursion stop condition
            if node is None:
                # create new node 
                new_node = TreeNode(val)
                # when we meet none,means we should insert node
                return new_node
            
            # recursion for single traversal
            if node.val > val:
                # mean's search left side tree
                node.left = traversal(node.left,val)
            if node.val < val:   
                # mean's search right side tree
                node.right = traversal(node.right,val)
            
            return node
        
        return traversal(root,val)
        

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

1. 没找到要删除的节点

2. 找到删除的点

   1. 删除的点是叶子节点

      1. 左为空右也为空

   2. 左不为空,右为空

      1. 让父节点直接指向左孩子

   3. 左为空,右不空

      1. 让父节点直接指向右孩子

   4. 左不空,右不空

      1. 让左右孩子其中一个继承父节点的位置,

         1. 如果让右孩子继承父节点位置,让左子树放在继承位置之前右子树的左孩子的下面

         2. 因为只有这个节点的值是要比父节点大一个数

C++ 伪代码

TreeNode * delete(root,key){
    // 递归停止条件; 删除的节点就是我们的停止条件
    if(root == Null){
        // 遍历到空了,返回null没找到要删除的节点
        return null
    }
    // 找到了删除的节点
    if(root->val == key){
        // 如果为叶子节点
        if(root->left == null && root->right == null){
            // 删除叶子节点,也就是说叶子节点的上一个节点会指向null
            // 这个 null在本层递归之后,会在下面有当前层的左子树等于下一层递归的返回值
            return null
        }
        // 左不为空,右为空
        else if(root->left != null && root->right == null){
            // 让删除的节点的左子树向上一层返回,这样要删除的节点就会被移除,
            // 因为删除节点上面的节点会接住 删除节点的返回值,这里的返回值就是删除节点的左子树
            return root.left 
        }
        // 左为空,右为空
        else if(root->left == null && root->right != null){
            // 逻辑跟上面一样
            return root->right
        }
        //左不空,右不空
        else{
            // 找到父节点右子树左孩子的值
            cur = root->right // 当前要删除的节点的右孩子
            // 只要当前节点左侧不为空就一直移动,直到叶子节点为止
            while cur->left != null{
                cur = cur->left
            }
            // 处理要移动的左子树
            cur->left = root->left
            
            // 这里移动完左子树之后,要删除节点的情况就是左为空,右不为空的情况,所以直接return root->right
            return root->right
        }
    }

    // 单层递归的逻辑

    if(key < root->val){
        // 向左侧搜索; 
        // 根节点应该指向,它的左子树删除掉key节点之后新的这个根节点返回给根节点
        root->left = delete(root->left,key)
    }

    if(key > root->val){
        // 向右搜索
        root->right = delete(root->right,key)
    }
    // 左右子树都处理完了,返回根节点
    return root
}

可运行代码

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def deleteNode(self, root, key):
        """
        :type root: TreeNode
        :type key: int
        :rtype: TreeNode
        """
        # recursion end condition
        if root is None:
            # we finished recursion, but can not find the node we want delete
            return root
        # we find the node we want delete
        if root.val == key:
            # if delete node is leaft node
            if root.left == None and root.right == None:
                # we let the child node pointer to none
                return None
            # if delete node right is empty
            elif root.left != None and root.right == None:
                # parent node we pointer to left node 
                return root.left
            elif root.left == None and root.right == None:
                return root.right
            else:
                # left and right both are NOT empty
                cur = root.right # use cur to store are right tree 
                # until reach the pare node right sub tree left side to empty
                while cur.left:
                    cur = cur.left
                
                # move are left sub tree 
                cur.left = root.left
                # after move the left sub tree to right sub tree child node
                # the situtaion is same as left empty right is not empty
                return root.right

        # recursion 
        if key < root.val:
            # search to left
            root.left = self.deleteNode(root.left,key)
        if key > root.val:
            # search to right
            root.right = self.deleteNode(root.right,key)
        # finished process left and right, return root
        return root

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值