标签:val 还需要 结构 exception 最好 运行时 += return enter
二叉查找树(Binary Search Tree)
, 简称BST
,必须具有以下性质:
小于
它的根结点的值大于
它的根结点的值在二叉查找树中查找节点时, 平均运行时间为O(logn)
(平衡情况), 最坏为O(n)
(极度不平衡), 平均深度是O(logn)
在有序数组中使用二分查找时最坏的时间复杂度是O(logn)
, 但是二叉搜索树的插入
和删除
的性能更优
二叉搜索树和数组对比
- | 数组 | 二叉搜索树 |
---|---|---|
查找 | 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)
散列表更加高效, 为什么还有二叉查找树?
标签:val 还需要 结构 exception 最好 运行时 += return enter
原文地址:https://www.cnblogs.com/zlone/p/11073558.html