二分查找树
python
from pprint import pformat
class Node:
def __init__(self, value, parent):
self.value = value
self.left = None
self.right = None
self.parent = parent
def __repr__(self):
if self.left is None and self.right is None:
return str(self.value)
return pformat({"%s" % (self.value): (
self.left, self.right)}, indent=1)
# 结点:(结点的左孩子,结点的右孩子)
class Bst:
def __init__(self, root=None):
self.root = root # self.read
def is_empty(self):
if self.root is None:
return True
else:
return False
def __str__(self):
return str(self.root)
def is_right(self, node):
return node == node.parent.right
# 查
def find(self, value):
if self.is_empty():
raise IndexError("空树不要查找了,找也找不到哒!!!")
else:
node = self.root
while node and node.value != value:
node = node.left if value < node.value else node.right
# print(node)
return node
#删
def remove(self, value: int):
search_node = self.find(value)
if search_node is not None:
if search_node.left is None and search_node.right is None:
self.__reassign_nodes(search_node, None)
elif search_node.left is None:
self.__reassign_nodes(search_node, search_node.right)
elif search_node.right is None:
self.__reassign_nodes(search_node, search_node.left)
else:
temp = self.get_max(search_node.left)
self.remove(temp.value)
search_node.value = temp.value
return search_node.value
def __reassign_nodes(self, node, new_children):
if new_children is not None:
new_children.parent = node.parent
if node.parent is not None:
if self.is_right(node):
node.parent.right = new_children
else:
node.parent.left = new_children
else:
self.root = new_children
def get_max(self, node=None):
if node is None:
node = self.root
if not self.is_empty():
while node.right is not None:
node = node.right
return node
def __insert(self, value):
new_node = Node(value, None) # 创建新结点
if self.is_empty():
self.root = new_node
else:
parent_node = self.root
while True:
if value < parent_node.value:
if parent_node.left is None:
parent_node.left = new_node
break
else:
parent_node = parent_node.left
elif value >= parent_node.value:
if parent_node.right is None:
parent_node.right = new_node
break
else:
parent_node = parent_node.right
new_node.parent = parent_node
def insert(self, *args):
for value in args:
self.__insert(value)
return self.root
# 前序遍历:
def fater(self,node):
if node is None:
return
print("%s"%node.value,end=" ")
self.fater(node.left)
self.fater(node.right)
return node
# 中序遍历:
def center(self,node):
if node is None:
return
self.center(node.left)
print("%s"%node.value,end=" ")
self.center(node.right)
return node
# 后序遍历:
def not_fater(self,node):
if node is None:
return
self.not_fater(node.left)
self.not_fater(node.right)
print("%s"%node.value,end=" ")
return node
if __name__ == '__main__':
j = Bst()
a = j.insert(2,5,4,7,9)
print("删除前树为: %s" % a)
print("查找的树为: %s" % j.find(4))
# print("删除的树为: %s" % j.remove(4))
print("删除后树为: %s" % a)
print("前序遍历为: 中左右: %s"%a,end=" ")
j.fater(j.root)
print()
print("中序遍历为: 左中右: %s"%a,end=" ")
j.center(j.root)
print()
print("后序遍历为: 左右中: %s"%a,end=" ")
j.not_fater(j.root)
解题思路:
增:
首先判断新添加的结点前有没有,如果有,再判断左子树为空吗,如果为空,就添加新的结点为左子树,如果不空,下移结点,右子树同理,如果结点前没有,则当前新添加的结点为根节点.
查:
首先看当前树为空吗,如果为空,就没有查的必要了,如果不为空,再判断当前节点不为空和当前节点的值不等于要找的值,如果当前节点不为空,并且当前值等于要找的值,直接返回这个值就好啦,如果不等于,就判断要查找的值是大于当前值的话,就往右下移结点,直到找到要查找的值,如果要查找的值小于当前值的话,就往左下移节点,直到找到要查找的值,最后返回找到的值.
删:
利用查找方法,找到我们要删除的值,
1.左右节点都为空:判断它的左节点为空,右节点也为空,就判断它的父节点的左孩子是它,就把它的父节点的左孩子指向空,如果它的父节点的右孩子是它,就把它的右孩子指向空
2.左节点为空,右节点不空,就把它的右节点的父节点,指向要删除的结点的父节点
3.右节点为空,左节点不空,就把它的左节点的父节点,指向要删除的结点的父节点
4.左右结点都不空,先找到当前值的左子树的最大值,之后删除这个最大值,让要删除的结点的值等于刚才删除的最大值
遍历:
1.前序遍历: 中左右
2.中序遍历: 左中右
3.后序遍历: 左右中