wuyijia

导航

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

[参考链接]

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

[注意]

1.因为是有序树,所以如果中间节点是 q 和 p 的公共祖先,那么中间节点的数组 一定是在[p, q]区间的。即中节点 > p && 中节点 < q 或者 中节点 > q && 中节点 < p。

2.那么只要从上到下去遍历,遇到 cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是q 和 p的公共祖先。 

3.遍历顺序无所谓,没有中间处理逻辑,只要有一个左一个右就可以.

[代码]

 1 # Definition for a binary tree node.
 2 # class TreeNode(object):
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution(object):
 9     def lowestCommonAncestor(self, root, p, q):
10         """
11         :type root: TreeNode
12         :type p: TreeNode
13         :type q: TreeNode
14         :rtype: TreeNode
15         """
16         #1.递归法
17         #
18         if root.val > p.val and root.val > q.val:
19             return self.lowestCommonAncestor(root.left, p, q)
20         #
21         if root.val < p.val and root.val < q.val:
22             return self.lowestCommonAncestor(root.right, p, q)
23         #cur处在中间
24         return root
25 
26         #2.迭代法
27         while True:
28             if root.val > p.val and root.val > q.val:
29                 root = root.left
30             elif root.val < p.val and root.val < q.val:
31                 root = root.right
32             else:
33                 return root

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

[注意]

1.只要遍历二叉搜索树,找到空节点 插入元素就可以了,

2.把添加的节点返回给上一层,就完成了父子节点的赋值操作了,

[代码]

 1 # Definition for a binary tree node.
 2 # class TreeNode(object):
 3 #     def __init__(self, val=0, left=None, right=None):
 4 #         self.val = val
 5 #         self.left = left
 6 #         self.right = right
 7 class Solution(object):
 8     def insertIntoBST(self, root, val):
 9         """
10         :type root: TreeNode
11         :type val: int
12         :rtype: TreeNode
13         """
14         # 返回更新后的以当前root为根节点的新树,方便用于更新上一层的父子节点关系链
15 
16         # Base Case
17         if not root: return TreeNode(val)
18 
19         # 单层递归逻辑:
20         if val < root.val: 
21             # 将val插入至当前root的左子树中合适的位置
22             # 并更新当前root的左子树为包含目标val的新左子树
23             root.left = self.insertIntoBST(root.left, val)
24 
25         if root.val < val:
26             # 将val插入至当前root的右子树中合适的位置
27             # 并更新当前root的右子树为包含目标val的新右子树
28             root.right = self.insertIntoBST(root.right, val)
29 
30         # 返回更新后的以当前root为根节点的新树
31         return root

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

[注意]

1.删除操作通过返回值进行操作,在停止条件里进行处理.

2.有以下五种情况:

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了
  • 找到删除的节点
    • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
    • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
    • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
    • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点.
    • [代码]
    •  1 # Definition for a binary tree node.
       2 # class TreeNode(object):
       3 #     def __init__(self, val=0, left=None, right=None):
       4 #         self.val = val
       5 #         self.left = left
       6 #         self.right = right
       7 class Solution(object):
       8     def deleteNode(self, root, key):
       9         """
      10         :type root: TreeNode
      11         :type key: int
      12         :rtype: TreeNode
      13         """
      14         #1.递归法
      15         if not root:#根节点为空,情况1
      16         #第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回None为根节点
      17             return None
      18         #向右遍历
      19         if key > root.val:
      20             root.right = self.deleteNode(root.right, key)
      21         #向左
      22         elif key < root.val:
      23             root.left = self.deleteNode(root.left, key)
      24  
      25         else:
      26             #第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
      27             if not root.left:
      28                 return root.right
      29 
      30             #第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
      31 
      32             if not root.right:
      33                 return root.left
      34 
      35             # 情况五:左右子树都不为空,找到右孩子的最左节点 记为node
      36             node = root.right
      37             while node.left:#右孩子左节点不为空,一直遍历
      38                 node = node.left
      39             # 将当前节点的左子树挂在node的左孩子上
      40             node.left = root.left
      41             # 当前节点的右子树替换掉当前节点,完成当前节点的删除
      42             root = root.right
      43 
      44         return root

       

posted on 2023-06-01 19:20  小吴要努力  阅读(11)  评论(0)    收藏  举报