1 二叉树遍历
二叉树遍历分为四种方式,分别是前序遍历,中序遍历,后序遍历和层序遍历
- 前序遍历顺序 根->左->右
- 中序遍历顺序 左->根->右
- 后序遍历顺序 右->左->根
- 层序遍历顺序 按层遍历
遍历二叉树最好的方式是使用递归的方式
如上图所示的二叉树,可以使用如下方式:
class Node:
def __init__(self,data):
self.data = data
self.lchild = None
self.rchild = None
self.parent = None
a = Node('A')
b = Node('B')
c = Node('C')
d = Node('D')
e = Node('E')
f = Node('F')
g = Node('G')
e.lchild = a
e.rchild = g
a.rchild = c
c.lchild = b
c.rchild = d
g.rchild = f
def pre_order(root):
if root:
print(root.data,end=',')
pre_order(root.lchild)
pre_order(root.rchild)
def in_order(root):
if root:
in_order(root.lchild)
print(root.data,end=',')
in_order(root.rchild)
def post_order(root):
if root:
post_order(root.rchild)
post_order(root.lchild)
print(root.data,end=',')
def level_order(root):
from collections import deque
q = deque()
q.append(root)
while len(q):
node = q.popleft()
print(node.data,end=',')
if node.lchild:
q.append(node.lchild)
if node.rchild:
q.append(node.rchild)
if __name__ == "__main__":
pre_order(e)
print("")
in_order(e)
print("")
post_order(e)
print("")
level_order(e)
"""
OUT
前序遍历:E,A,C,B,D,G,F,
中序遍历:A,B,C,D,E,G,F,
后序遍历:F,G,D,B,C,A,E,
层序遍历:E,A,G,C,F,B,D,
"""
已知任意两种遍历结果,可以还原一颗树
前序遍历:E,A,C,B,D,G,F, 中序遍历:A,B,C,D,E,G,F,
step1:前序遍历第一个结点肯定是根节点,得E是根节点 step2:中序遍历E左边的位置ABCD是左子树群,GF是右子树群 step3:前序遍历第二个结点是A,中序遍历第一个结点是A,说明A是E的左子树,G是E的右子树,第二层还原完成 step4:中序遍历第一个结点就是A,说明A没有左子树,C是A的右子树 step5:前序遍历CBD,中序遍历BCD,说明C的左子树是B,右子树是D step6: F是G的右节点 根据不同遍历执行的顺序是可以还原整颗树的
2 二叉树搜索树
2.1 插入
新建一个结点
class BiTreeNode:
def __init__(self,data):
self.data = data
self.lchild = None
self.rchild = None
self.parent = None
递归方式插入
class BiTree:
def __init__(self,li=None):
self.root = None
if li:
for i in li:
self.insert_no_rec(i)
def insert(self,node,val):
if not node:
node = BiTreeNode(val)
elif val < node.data:
node.lchild = self.insert(node.lchild,val)
node.lchild.parent = node
elif val > node.data:
node.rchild = self.insert(node.rchild,val)
node.rchild.parent = node
return node
非递归方式插入
def insert_no_rec(self,val):
curent = self.root
if not curent:
self.root = BiTreeNode(val)
return
while True:
if val > curent.data:
if curent.rchild:
curent = curent.rchild
else:
curent.rchild = BiTreeNode(val)
curent.rchild.parent = curent
return
elif val<curent.data:
if curent.lchild:
curent = curent.lchild
else:
curent.lchild = BiTreeNode(val)
curent.lchild.parent = curent
return
else:
return
2.2 查询
def select(self,val):
p = self.root
if not p:
return False
while True:
if val<p.data:
if p.lchild:
p = p.lchild
else:
return None
elif val>p.data:
if p.rchild:
p = p.rchild
else:
return None
else:
return p
2.3 删除
二叉搜索树的删除时比较复杂的,可以分为三种不同的情况
删除的结点时叶子结点,没有任何子节点,这种情况就直接删除掉
def __remove_node_1(self,node):
if not node.parent:
self.root = None
if node == node.parent.lchild:
node.parent.lchild = None
node.parent = None
else:
node.parent.rchild = None
node.parent = None
删除的结点有一个孩子,结点的父结点直接链接这个要删除结点的孩子结点
def __remove_node_2_1(self,node):
if node == node.parent.lchild:
node.parent.lchild = node.lchild
node.lchild.parent = node.parent
else:
node.parent.rchild = node.lchild
node.lchild.parent = node.parent
def __remove_node_2_2(self,node):
if node == node.parent.lchild:
node.parent.lchild = node.rchild
node.rchild.parent = node.parent
else:
node.parent.rchild = node.rchild
node.rchild.parent = node.parent
删除的结点是根节点,找到这个根节点右节点的最小子节点,与这个根节点替换掉,然后删除这个子节点
def delete(self,val):
node = self.select(val)
if node:
if not node.lchild and not node.rchild:
self.__remove_node_1(node)
elif not node.rchild:
self.__remove_node_2_1(node)
elif not node.lchild:
self.__remove_node_2_2(node)
else:
min_node = node.rchild
while min_node.lchild:
min_node = min_node.lchild
node.data = min_node.data
self.__remove_node_1(min_node)
3 附完整代码
class BiTreeNode:
def __init__(self,data):
self.data = data
self.lchild = None
self.rchild = None
self.parent = None
class BiTree:
def __init__(self,li=None):
self.root = None
if li:
for i in li:
self.insert_no_rec(i)
def insert(self,node,val):
if not node:
node = BiTreeNode(val)
elif val < node.data:
node.lchild = self.insert(node.lchild,val)
node.lchild.parent = node
elif val > node.data:
node.rchild = self.insert(node.rchild,val)
node.rchild.parent = node
return node
def insert_no_rec(self,val):
curent = self.root
if not curent:
self.root = BiTreeNode(val)
return
while True:
if val > curent.data:
if curent.rchild:
curent = curent.rchild
else:
curent.rchild = BiTreeNode(val)
curent.rchild.parent = curent
return
elif val<curent.data:
if curent.lchild:
curent = curent.lchild
else:
curent.lchild = BiTreeNode(val)
curent.lchild.parent = curent
return
else:
return
def in_order(self,root):
if root:
self.in_order(root.lchild)
print(root.data,end=',')
self.in_order(root.rchild)
def pre_order(self,root):
if root:
print(root.data,end=',')
self.pre_order(root.lchild)
self.pre_order(root.rchild)
def post_order(self,root):
if root:
self.post_order(root.rchild)
self.post_order(root.rchild)
print(root.data,end=',')
def level_order(self,root):
from collections import deque
q = deque()
q.append(root)
while len(q) > 0:
node = q.popleft()
print(node.data,end=',')
if node.lchild:
q.append(node.lchild)
if node.rchild:
q.append(node.rchild)
def select(self,val):
p = self.root
if not p:
return False
while True:
if val<p.data:
if p.lchild:
p = p.lchild
else:
return None
elif val>p.data:
if p.rchild:
p = p.rchild
else:
return None
else:
return p
def __remove_node_1(self,node):
if not node.parent:
self.root = None
if node == node.parent.lchild:
node.parent.lchild = None
node.parent = None
else:
node.parent.rchild = None
node.parent = None
def __remove_node_2_1(self,node):
if node == node.parent.lchild:
node.parent.lchild = node.lchild
node.lchild.parent = node.parent
else:
node.parent.rchild = node.lchild
node.lchild.parent = node.parent
def __remove_node_2_2(self,node):
if node == node.parent.lchild:
node.parent.lchild = node.rchild
node.rchild.parent = node.parent
else:
node.parent.rchild = node.rchild
node.rchild.parent = node.parent
def delete(self,val):
node = self.select(val)
if node:
if not node.lchild and not node.rchild:
self.__remove_node_1(node)
elif not node.rchild:
self.__remove_node_2_1(node)
elif not node.lchild:
self.__remove_node_2_2(node)
else:
min_node = node.rchild
while min_node.lchild:
min_node = min_node.lchild
node.data = min_node.data
self.__remove_node_1(min_node)
|