二叉查找树
1. 定义
二叉查找树(Binary Search Tree),也称二叉搜索树、有序二叉树(ordered binary tree),排序二叉树(orted binary tree),是指一棵空树或者具有下列性质的二叉树:
- 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
- 任意节点的左、右子树也分别为二叉查找树;
- 没有键值相等的节点
二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低,均为O(log n)
2. 基本操作
1. 查找
在二叉树b中查找x的过程为:
- 若b是空树,则搜索失败,否则:
- 若x等于b的根节点的数据域之值,则查找成功;否则:
- 若x小于b的根节点的数据域之值,则递归搜索左子树;否则:
- 递归查找右子树
def searchBST(root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
if not root:
return None
if root.val == val:
return root
if root.val > val:
return searchBST(root.left, val)
else:
return searchBST(root.right, val)
Average case: O(H)/O(logN), H is a tree height.
Worst case: O(N)
Sample code: Here
2. 插入
向一个二叉搜索树b中插入一个节点s的算法,过程为:
- 若b是空树,则将s所指结点作为根节点插入,否则:
- 若s.val等于b的根节点的数据域之值,则返回,否则:
- 若s.val小于b的根节点的数据域之值,则把s所指节点插入到左子树中,否则:
- 把s所指节点插入到右子树中**(新插入节点总是叶子节点)**
def insertIntoBST(root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
if root == None:
return TreeNode(val)
if root.val > val:
root.left = self.insertIntoBST(root.left, val)
elif root.val < val:
root.right = self.insertIntoBST(root.right, val)
return root
Average case: O(logN)
Worst case: O(N)
Sample code: Here
3. 删除
删除分三种情况讨论
- 如果是leaf,直接删除
- 如果有一个子节点,用子节点替换
- 如果有两个子节点,找到successor(right tree中最小的node),用successor替换,并把successor删除
class Solution(object):
# The functions to find successor and predecessor are based on the assumption that root has two children.
def successor(self, root):
root = root.right
while root.left:
root = root.left
return root
def predecessor(self, root):
root = root.left
while root.right:
root = root.right
return root
def deleteNode(self, root, key):
"""
:type root: TreeNode
:type key: int
:rtype: TreeNode
"""
if not root:
return None
if root.val > key:
root.left = self.deleteNode(root.left, key)
elif root.val < key:
root.right = self.deleteNode(root.right, key)
# delete the current node
else:
# the node is a leaf
if not root.left and not root.right:
root = None
# the node has two children
elif root.right:
successor = self.successor(root)
root.val = successor.val
root.right = self.deleteNode(root.right, root.val)
# the node has only left child
elif root.left:
predecessor = self.predecessor(root)
root.val = predecessor.val
predecessor = None
root.left = self.deleteNode(root.left, root.val)
return root
Average case: O(logN)
Worst case: O(N)
Sample code: Here
4. 遍历
Inorder Traversal保证升序输出
Algorithm:
def traverse_binary_tree(root):
if root is None:
return
traverse_binary_tree(root.left)
print(root.value)
traverse_binary_tree(root.right)
5. Find inorder successor of p in BST
- 如果p.right不为None: 直接找successor; 否则
- 进行inorder traversal,找到p的successor
class Solution(object):
def inorderSuccessor(self, root, p):
"""
:type root: TreeNode
:type p: TreeNode
:rtype: TreeNode
"""
# if successor in the lower right tree
if p.right:
p = p.right
while p.left:
p = p.left
return p
# if successor in the upper tree
stack = []
inorder = float('inf')
while stack or root:
while root:
stack.append(root)
root = root.left
root = stack.pop()
if inorder == p.val:
return root
inorder = root.val
root = root.right
return None