二叉查找树(Binary Search Tree)
, 简称BST
,必须具备如下性质:node
小于
它的根结点的值大于
它的根结点的值在二叉查找树中查找节点时, 平均运行时间为O(logn)
(平衡状况), 最坏为O(n)
(极度不平衡), 平均深度是O(logn)
python
在有序数组中使用二分查找时最坏的时间复杂度是O(logn)
, 可是二叉搜索树的插入
和删除
的性能更优git
二叉搜索树和数组对比github
- | 数组 | 二叉搜索树 |
---|---|---|
查找 | O(logn)(二分查找) | O(logn) |
插入 | O(n) | O(logn) |
删除 | O(n) | O(logn) |
插入/查找/删除
最大/最小
节点# coding:utf-8 class TreeNode(object): def __init__(self, key, value, parent=None, left=None, right=None): self.key = key self.value = value self.parent = parent self.left = left self.right = right def isLeftChild(self): return self.parent and self.parent.left == self def isRightChild(self): return self.parent and self.parent.right == self def childrenNums(self): num = 0 if self.left: num += 1 if self.right: num += 1 return num class BinarySearchTree(object): def __init__(self): self.root = None self.size = 0 def put(self, key, value): if self.root: self._put(key, value, self.root) else: self.root = TreeNode(key, value) self.size += 1 def _put(self, key, value, current): if key < current.key: if current.left: self._put(key, value, current.left) else: current.left = TreeNode(key, value, parent=current) elif key > current.key: if current.right: self._put(key, value, current.right) else: current.right = TreeNode(key, value, parent=current) def get(self, key): if self.root: res = self._get(key, self.root) else: return None return res def _get(self, key, current): if not current: return None if key < current.key: return self._get(key, current.left) elif key > current.key: return self._get(key, current.right) else: return current def delete(self, key): if self.size > 1: # 要先找到该节点 node2remove = self.get(key) if node2remove: self.remove(node2remove) self.size -= 1 else: raise Exception('no element') elif self.size == 1 and self.root.key == key: self.root = None self.size -= 1 else: raise Exception('no element') def remove(self, current): childrens = current.childrenNums() if 0 == childrens: if current.isLeftChild(): current.parent.left = None else: current.parent.right = None elif 1 == childrens: # 若是该节点有左子树 if current.left: if current.isLeftChild(): current.left.parent = current.parent current.parent.left = current.left elif current.isRightChild(): current.left.parent = current.parent current.parent.right = current.left else: self.root = current.left # 若是是右子树 elif current.right: if current.isLeftChild(): current.right.parent = current.parent current.parent.left = current.right elif current.isRightChild(): current.right.parent = current.parent current.parent.right = current.right else: self.root = current.right # 若是有两个子节点 else: parent = current minChild = current.right while minChild.left != None: parent = minChild minChild = minChild.left current.key = minChild.key current.value = minChild.value # 注意如下状况判断, 由于有的没有左子节点 if parent.left == minChild: parent.left = minChild.right if minChild.right: minChild.right.parent = parent else: parent.right = minChild.right if minChild.right: minChild.right.parent = parent def length(self): return self.size def __setitem__(self, key, value): self.put(key, value) def __getitem__(self, key): return self.get(key) def __delitem__(self, key): self.delete(key) def mid(self, root): if not root: return self.mid(root.left) print(root.value) self.mid(root.right) if __name__ == '__main__': mytree = BinarySearchTree() mytree[7] = "7" mytree[2] = "2" mytree[11] = "11" mytree[8] = "8" mytree[19] = "19" mytree[5] = "5" mytree[1] = "1" # 中序遍历 mytree.mid(mytree.root) print('------') # 删除叶子节点1 del mytree[1] mytree.mid(mytree.root) print('------') # 删除有一个子节点的2 del mytree[2] mytree.mid(mytree.root) print('------') # 删除有两个子节点的11 del mytree[11] mytree.mid(mytree.root)
散列表更加高效, 为何还有二叉查找树?算法