"""
二叉树:插入 删除 查找
"""
from exer4 import SQueue # 见队列实现
import random
class Node:
"""
节点类,
"""
__slots__ = ["__value", "__left", "__right"]
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
@property
def value(self):
return self.__value
@value.setter
def value(self, value):
if isinstance(value, int):
self.__value = value
else:
raise ValueError("value should be an instance of int")
@property
def left(self):
return self.__left
@left.setter
def left(self, node):
if isinstance(node, Node) or node is None:
self.__left = node
else:
raise ValueError("node should be an instance of Node")
@property
def right(self):
return self.__right
@right.setter
def right(self, node):
if isinstance(node, Node) or node is None:
self.__right = node
else:
raise ValueError("node should be an instance of Node")
class BiTree:
"""
二叉树类:传入一个整数,把这个值生成的节点插入到二叉树中,这个节点的值,大于左孩子的值,小于等于右孩子的值
"""
def __init__(self):
self.__root = None
def make_bitree(self, lis):
"""
用传入列表中的节点生成一棵二叉树
:param lis:
:return: 返回生成二叉树的根节点
"""
if not isinstance(lis, list):
raise TypeError("lis should be a instance of list")
root = lis[0]
root.left = None
root.right = None
for item in lis[1:]:
item.left = None
item.right = None
self.__insert2(item, root)
return root
def find_node(self, value):
"""
查找二叉树中是否存在值为value的节点,存在返回这个节点
:param value: 传入值
:return: (bool, node)
"""
root = self.__root
while root is not None and value != root.value:
if root.value > value:
root = root.left
else:
root = root.right
if root is None:
return False, None
else:
return True, root
def __hierarchy_tranverse(self, node_queue):
"""
传入同一深度的节点组成的队列,按从同一深度从左到右,深度从上到下排列的node组成的数组
:param node_queue:
:return:
"""
queue = SQueue(100)
lst = []
while not node_queue.is_empty():
node = node_queue.dequeue()
lst.append(node)
if node.left is not None:
queue.enqueue(node.left)
if node.right is not None:
queue.enqueue(node.right)
if not queue.is_empty():
rtn_lst = self.__hierarchy_tranverse(queue)
lst.extend(rtn_lst)
return lst
def hirerarchy_tranverse(self):
"""
层次遍历,返回一个列表,列表中节点按从上倒下从左到右顺序在列表中排列
:return:
"""
queue = SQueue(100)
queue.enqueue(self.__root)
return self.__hierarchy_tranverse(queue)
def delete_value(self, value):
"""
删除值为value的节点,返回(bool, node),如果不存在这个值的节点则返回(False, None)
:param value:传入值
:return:
"""
rtn, node = self.find_node(value)
if not rtn:
return False, None
prev, sid = self.find_previous_node(node)
if prev is None:
lis = self.hirerarchy_tranverse()
self.__root = self.make_bitree(lis[1:])
else:
if node.left is None and node.right is None:
if sid == 0:
prev.left = None
else:
prev.right = None
elif node.left is not None and node.right is not None:
queue = SQueue()
queue.enqueue(node)
lis = self.__hierarchy_tranverse(queue)
newroot = self.make_bitree(lis[1:])
if sid == 0:
prev.left = newroot
else:
prev.right = newroot
elif node.left is not None:
if sid == 0:
prev.left = node.left
else:
prev.right = node.left
else:
if sid == 0:
prev.left = node.right
else:
prev.right = node.right
return True, node
def __find_previous_node(self, node, root):
"""
从root开始,查找node节点的父节点,如果找到,返回这个父节点以及是父节点的左节点(0)还是右节点(1)
这个节点的父节点不存在,则返回(None,-1)
:param node:要查找的节点
:param root: 从这个节点开始查找
:return: (父节点,左节点/右节点)
"""
if root is None or root == node:
return None, -1
elif root.left == node:
return root, 0
elif root.right == node:
return root, 1
if root.left is not None:
(prev, sid) = self.__find_previous_node(node, root.left)
if prev is not None:
return prev, sid
return self.__find_previous_node(node, root.right)
def find_previous_node(self, node):
return self.__find_previous_node(node, self.__root)
def insert2(self, value):
node = Node(value)
if self.__root is None:
self.__root = node
else:
self.__insert2(node, self.__root)
def __insert2(self, node, root):
"""
采用递归方式插入
:param node:
:param root:
:return:
"""
if root is None:
return
if root.left is None and root.right is None:
if root.value > node.value:
root.left = node
else:
root.right = node
elif root.left is not None and root.right is None:
if root.value > node.value:
self.__insert2(node, root.left)
else:
root.right = node
elif root.left is None and root.right is not None:
if root.value > node.value:
root.left = node
else:
self.__insert2(node, root.right)
else:
if root.value > node.value:
self.__insert2(node, root.left)
else:
self.__insert2(node, root.right)
def insert(self, value):
"""
向二叉树中插入一个值
:param value:
:return: 无
"""
node = Node(value)
if self.__root is None:
self.__root = node
else:
self.__insert(node, self.__root)
def __insert(self, node, root):
"""
把传入的节点插入到以root为根的二叉树中
:param node:
:param root:
:return:
"""
while root is not None:
current = root
if node.value < root.value:
root = root.left
else:
root = root.right
if node.value < current.value:
current.left = node
else:
current.right = node
def __front_tranverse(self, root):
if root is None:
return
print("%5d" % root.value, end=" ")
if root.left is None and root.right is None:
return
self.__front_tranverse(root.left)
self.__front_tranverse(root.right)
def __middle_tranverse(self, root):
if root is not None:
if root.left is None:
print("%5d" % root.value, end=" ")
self.__middle_tranverse(root.right)
else:
self.__middle_tranverse(root.left)
print("%5d" % root.value, end=" ")
self.__middle_tranverse(root.right)
def __last_tranverse(self, root):
if root is not None:
self.__last_tranverse(root.left)
self.__last_tranverse(root.right)
print("%5d" % root.value, end=" ")
def last_tranverse(self):
"""
后序遍历二叉树
:return:
"""
self.__last_tranverse(self.__root)
print()
def middle_tranverse(self):
"""中序遍历二叉树"""
self.__middle_tranverse(self.__root)
print()
def front_tranverse(self):
"""
后续遍历二叉树
:return:
"""
self.__front_tranverse(self.__root)
print()
if __name__ == "__main__":
"""二叉树测试"""
bitree1 = BiTree()
bitree2 = BiTree()
i = 1
# tmp = []
# while i < 15:
# rnd = random.randint(1, 100)
# if rnd not in tmp:
# tmp.append(rnd)
# else:
# continue
# i += 1
tmp = [84, 19, 47, 81, 51, 62, 74, 31, 20, 27, 57, 44, 85, 88]
print("原数组:", tmp)
for val in tmp:
bitree1.insert(val)
bitree2.insert2(val)
print("先序遍历:", end=" ")
bitree1.front_tranverse()
print("中序遍历:", end=" ")
bitree1.middle_tranverse()
print("后序遍历:", end=" ")
bitree1.last_tranverse()
print("层级遍历:", end=" ")
node_lst = bitree1.hirerarchy_tranverse()
for node in node_lst:
print("%5d" % node.value, end=" ")
print()
"""测试二叉树递归插入:"""
print("*" * 20)
print("测试二叉树递归插入")
print("先序遍历:", end=" ")
bitree2.front_tranverse()
print("中序遍历:", end=" ")
bitree2.middle_tranverse()
print("后序遍历:", end=" ")
bitree2.last_tranverse()
print("层级遍历:", end=" ")
lst = bitree2.hirerarchy_tranverse()
for node in lst:
print("%5d" % node.value, end=" ")
print()
"""测试查找"""
print("测试查找:")
rtn, node = bitree1.find_node(51)
if rtn:
print("value=%d" % node.value)
previous, side = bitree1.find_previous_node(node)
if previous is not None:
print("side:%d value:%d" % (side, previous.value))
rtn, node = bitree1.delete_value(85)
if rtn:
print("删除节点:%d" % node.value)
print("先序遍历:", end=" ")
bitree1.front_tranverse()
rtn2, node2 = bitree1.find_node(88)
if rtn2:
prev2, sid2 = bitree1.find_previous_node(node2)
print("被删除节点的前一个节点:%d,side:%d" % (prev2.value, sid2))
测试结果: