代码随想录:二叉搜索树

76 阅读2分钟

今天做divide and conquer的题目时见到了1382这个题目,于是找到代码随想录里面对应的二叉搜索树整体练习了一下。二叉搜索树主要分为:搜寻,构造,判断,反构造,增加与删除节点,修剪。二叉搜索树的核心就是基于它本身的从左子树到右子树逐渐加大的特性。

二叉搜索树的构造

运用二叉搜索树进行查找

题目链接:700. Search in a Binary Search Tree

    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        #base case
        if root is None or root.val == val:
            return root
        
        if root.val > val:
            return self.searchBST(root.left,val)
        if root.val < val:
            return self.searchBST(root.right,val)

二叉搜索树拆分为数组

题目链接:98. Validate Binary Search Tree

根据二叉搜索树的特性我们知道它从小到大的排列是左子树-根节点-右子树,正好对应了中序遍历的左-中-右的遍历顺序

    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        res = []

        def in_order(root,res):
            if not root:
                return
            in_order(root.left,res)
            res.append(root.val)
            in_order(root.right,res)

        in_order(root,res)
        for i in range(1,len(res)):
            if res[i-1] >= res[i]:
                return False
        return True

将数组转化为二叉搜索树

二叉搜索树的编辑

插入节点

题目链接:701. Insert into a Binary Search Tree

插入节点其实就是在搜素节点的基础上多了一步,在搜索到可以插入该值的合适的位置(空节点)之后,只要决定是将val插入为节点的左孩子(left child)还是右孩子(right child),同时返回我们插入的节点。

        if not root:
            node = TreeNode(val)
            return node
        if root.val > val:
            root.left = self.insertIntoBST(root.left,val) #注意这里要用root.left来接住我们插入的node以保持树的结构
        if root.val < val:
            root.right = self.insertIntoBST(root.right,val)
        
        return root

删除节点

删除节点相对于插入节点来说更复杂,先写出删除的节点可能会有的五种情况:

  1. 空节点
    if not root:
        return root

下面四种情况的大前提:if root.val == key

  1. 叶节点(左右孩子为空节点):返回空节点
    if root.left is None and root.right is None:
        return None
  1. 左孩子为空:此时右孩子补位,为了使父节点指向补位的节点return root.right
    if root.left is None:
        return root.right
  1. 右孩子为空
    if root.right is None:
        return root.left
  1. 左右都不为空: 则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置
   #先找到右子树最左的叶节点
   node = root.right
   while node.left:
       node = node.left
   #插入左子树
   node.left = root.left
   #父节点指向补位的节点
   return root.right

修剪二叉搜索树