今天做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
删除节点
删除节点相对于插入节点来说更复杂,先写出删除的节点可能会有的五种情况:
- 空节点
if not root:
return root
下面四种情况的大前提:if root.val == key
- 叶节点(左右孩子为空节点):返回空节点
if root.left is None and root.right is None:
return None
- 左孩子为空:此时右孩子补位,为了使父节点指向补位的节点
return root.right
if root.left is None:
return root.right
- 右孩子为空
if root.right is None:
return root.left
- 左右都不为空: 则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置
#先找到右子树最左的叶节点
node = root.right
while node.left:
node = node.left
#插入左子树
node.left = root.left
#父节点指向补位的节点
return root.right