Binary Search Tree
每个node,比左child最大的大,比右child最小的小
Implementation
class _Node(object):
def __init__(self, key, value):
self.key = key
self.value = value
self.left = self.right = None
class BinarySearchTree(object):
def __init__(self):
self.__root = None
def __query(self, root, key):
if not root:
return None
if key<root.key:
return self.__query(root.left, key)
elif key>root.key:
return self.__query(root.right, key)
else:
return root.value
def query(self, key):
return self.__query(self.__root, key)
def FindMinimum(self, root):
if not root:
return None
return FindMinimum(self.left) or root
def FindFirstLargerThanTarget(self, root, target):
if not root:
return None
if root.value == target:
return self.FindMinimum(root.right)
elif root.value < target:
return self.FindFirstLargerThanTarget(root.right, target)
else:
return self.FindFirstLargerThanTarget(root.left, target) or root
def FindLastSmallerThanTarget(self, root, target):
pass
def insert(self, key, value):
self.__root = self.__insert(self.__root, key, value)
def __insert(self, root, key, value):
if not root:
return _Node(key, value) #这个时候就只是new了一个新的node
if key < root.key:
root.left = self.__insert(root.left, key, value) #在dereference这里才把那个new出来的node挂在对应的位置上
elif key > root.key:
root.right = self.__insert(root.right, key, value) #一个个往上挂回去 最后回去的时候就能回到正确的
else:
root.value = value
return root
# 如果没有等号/if里面是return,那么回去的只是这个node而已
# heap上:new出来了node,dereference的写
# 刚才的子树,怎么来怎么挂,无差别的写
# 如果return null 那么就做了pruning,一半的枝都没了
# 三部曲:所有判断往下走;下层返回的挂上去;操作完的结果通过return来report给上一层
def __deleteMin(self, root):
if not root.left:
return root.right
root.left = self.__deleteMin(root.left)
return root
def __delete(self, root, key):
if not root:
return None
if key < root.key:
root.left = self.__delete(root.left, key)
elif key > root.key:
root.right = self.__delete(root.right, key)
else:
if not root.right:
return root.left
if not root.left:
return root.right
t = root
root = self.__min(t.right)
root.right = self.__deleteMin(t.right)
root.left = t.left
return root
def delete(self, key):
self.__root = self.__delete(self.__root, key)也可以iteratively query和insert
检查是否BST
左节点, lower bound来自parent的lower bound, upper bound来自parent的值;
右节点, lower bound 来自parent的值,upper bound来自parent的upper bound
方法一: 从上往下传值
为了维护BST的性质,每一个node都必须有自己的(min max)区间,只要保证每一个node都在自己的区间内,就是BST,但凡有一个跳出了这个range,就不是BST。
line 14必须是闭,因为min max的物理意义都是exclusive
Time=O(n)
Space=O(height)
方法二:从下往上返值
左边是否BST,右边是否BST,左边的max是否小于root,右边的min是否大于root 左边的max,右边的min,以及一个boolean 分别是否是BST 只是需要注意,如果左max右min是None的话,就用root.val
方法三:inorder打印,应该ascending order
step 1: inorder traverse the tree and store all elements in an array step 2: iterate over the array to determine whether a[i] <a[i+1] space consumption 很糟糕 Space O(n) Time O(n)
或者不存array,边traverse边比较 Space O(height) Time O(n)
Create a BST from a sorted list of integers
Given the following sequence:
in-order: 1 2 4 6 7 8 9 10 12
How many BSTs can you create for n input numbers?
For 0 or 1 number, just 1 unique tree, None or TreeNode(x);
For n>1, there will be 1 value at root, with whatever remains on the left and right to form separate subtrees. Iterate through all the values that could be the root.
count =0
count += count_trees(i-1)*count_trees(n-i), for i in range(i, n+1)
Another similar problem is counting the # of valid parenthesis.
Catalan Number
Which is the best one?
—— Balanced Tree
利用BST的性质
BST版的LCA
BST版的search element
return以它为root的subtree
Range Sum of BST
Given the root node of a BST, return the sum of values of all nodes with the value between l and r (inclusive).
Get Keys In Binary Search Tree In Given Range
Time: worst case O(n) 更紧凑的Time complexity: O(height+# of nodes in the range of [k1, k2]) Space: O(height), worst case O(n)
Search in BST
Insert in BST
Delete
Last updated