二叉树具有天然递归结构
一个节点也是二叉树
NULL也是二叉树
二分搜索树是二叉树
每个节点的左子树也是二叉树
每个节点的右子树也是二叉树
二分搜索树的每个节点的值:
大于其左子树所有节点的值
小于其右子树所有节点的值
中序遍历的结果是顺序的
后序遍历的一个应用:
为二分搜索树释放内存
这里实现了二分搜索树的基本功能,包括插入、删除、查询等功能,后期会添加一些rank、select、floor、ceil等功能
from queue import Queue
from random import randint
class BSTree(object):
class Node():
def __init__(self,key,value):
self.key = key #关键字
self.value = value
self.left = None #左孩子
self.right = None #右孩子
def __init__(self):
self.__root = None
self.__count = 0
def size(self):
return self.__count
def isEmpty(self):
return self.__count==0
# 插入一个新的节点,返回插入新节点后的二分搜索树的根,使用递归算法
def add(self,key,value):
self.__root = self.__add(self.__root, key, value)
def __add(self,node,key,value):
if node is None:
self.__count+=1
return self.Node(key, value)
if key == node.key:
node.value = value
elif key > node.key:
node.right = self.__add(node.right, key, value)
else:
node.left = self.__add(node.left, key, value)
return node
# 以node为根的二分搜索树中是否包含键值为key的节点,使用递归算法
def contains(self,key):
return self.__contains(self.__root, key)
def __contains(self,node,key):
if node is None:
return False
if key==node.key:
return True
elif key > node.key:
return self.__contains(node.right, key)
elif key < node.key:
return self.__contains(node.left, key)
# 二分搜索树的前序遍历
def preOrder(self):
self.__preOrder(self.__root)
# 前序遍历以node为根节点的二分搜索树,递归算法
def __preOrder(self, node):
if node != None:
print(node.key)
self.__preOrder(node.left)
self.__preOrder(node.right)
# 二分搜索树的非递归前序遍历
def preOrderNR(self):
stack = []
stack.append(self.__root)
while len(stack) != 0:
node = stack.pop()
print(node.key)
if node.right != None:
stack.append(node.right)
if node.left != None:
stack.append(node.left)
# 二分搜索树的中序遍历
# 中序遍历的结果是顺序的
def inOrder(self):
self.__inOrder(self.__root)
#中序遍历以node为根节点的二分搜索树,递归算法
def __inOrder(self, node):
if node != None:
self.__inOrder(node.left)
print(node.key)
self.__inOrder(node.right)
# 二分搜索树的后序遍历
# 后序遍历的一个应用:为二分搜索树释放内存
def postOrder(self):
self.__postOrder(self.__root)
# 后序遍历以node为根节点的二分搜索树,递归算法
def __postOrder(self, node):
if node != None:
self.__postOrder(node.left)
self.__postOrder(node.right)
print(node.key)
# 二分搜索树的层序遍历
def levelOrder(self):
q = Queue()
q.put(self.__root)
while not q.empty():
node = q.get()
print(node.key)
if node.left != None:
q.put(node.left)
if node.right != None:
q.put(node.right)
# 寻找二分搜索树的最小元素
def minimum(self):
try:
return self.__minimum(self.__root).key
except Exception as e:
print("BST is empty!")
# 返回以node为根的二分搜索树的最小值所在的节点
def __minimum(self, node):
if node.left == None:
return node
return self.__minimum(node.left)
# 寻找二分搜索树的最大元素
def maximum(self):
try:
return self.__maximum(self.__root).key
except Exception as e:
print("BST is empty!")
# 返回以node为根的二分搜索树的最大值所在的节点
def __maximum(self, node):
if node.right == None:
return node
return self.__maximum(node.right)
# 从二分搜索树中删除最小值所在节点,返回最小值
def removeMin(self):
ret = self.minimum()
self.__root = self.__removeMin(self.__root)
return ret
# 删除掉以node为根的二分搜索树中的最小节点
# 返回删除节点后新的二分搜索树的根
def __removeMin(self, node):
if node.left == None:
rightNode = node.right
node.right == None
self.__count -= 1
return rightNode
node.left = self.__removeMin(node.left)
return node
# 从二分搜索树中删除最大值所在节点,返回最大值
def removeMax(self):
ret = self.maximum()
self.__root = self.__removeMax(self.__root)
return ret
# 删除掉以node为根的二分搜索树中的最大节点
# 返回删除节点后新的二分搜索树的根
def __removeMax(self, node):
if node.right == None:
leftNode = node.left
node.left == None
self.__count -= 1
return leftNode
node.right = self.__removeMax(node.right)
return node
# 从二分搜索树中删除元素为key的节点
def remove(self, key):
self.__root = self.__remove(self.__root, key)
# 删除以node为根的二分搜索树中值为e的节点, 递归算法
# 返回删除节点后的新的二分搜索树的根
def __remove(self, node, key):
if node == None:
return None
if node.key > key:
leftNode = self.__remove(node.left, key)
return leftNode
elif node.key < key:
rightNode = self.__remove(node.right, key)
return rightNode
else: #node.key==key
# 待删除的节点左子树为空
if node.left == None:
rightNode = node.right
node.right = None
self.__count -= 1
return rightNode
# 待删除的节点右子树为空
if node.right == None:
leftNode = node.left
node.left = None
self.__count -= 1
return leftNode
# 待删除的节点左右子树均不为空
# 找到比待删除节点大的最小节点,即待删除节点右子树的最小节点
# 用这个节点顶替待删除节点的位置
successor = self.__minimum(node.right)
successor.right = self.__removeMin(node.right)
successor.left = node.left
node.left = node.right = None
return successor
if __name__ == '__main__':
#arr = [randint(0,1000) for x in range(1,100)]
arr = [28, 30, 16, 13, 29, 22, 42]
#print(arr)
bst = BSTree()
for i in range(0, len(arr)):
bst.add(arr[i], str(arr[i]))
'''
print(bst.contains(56))
print(bst.size())
print(bst.isEmpty())
bst.preOrder()
print("\n")
bst.preOrderNR()
bst.inOrder()
print("\n")
bst.postOrder()
bst.levelOrder()
'''
bst.inOrder()
print("\n")
print("最小值为:",bst.minimum())
print("删除:",bst.removeMin(),",删除后最小值为:",bst.minimum())
print("最大值为:", bst.maximum())
print("删除:", bst.removeMax(), ",删除后最大值为:", bst.maximum())
bst.inOrder()
e = int(input("你想删除:"))
bst.remove(e)
bst.inOrder()