ACM模式下输入输出是一个非常令人头痛的问题,尤其是树的输入输出。习惯了只写核心代码的模式,毫无疑问,第一次做题直接就成了炮灰,所以在这里对树的各种遍历方式和创建方式做个总结。
创建二叉树
方法一:先序创建
class TreeNode(object):
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def creat_tree(input_list):
if len(input_list) == 0 or input_list is None:
return None
data = input_list.pop(0)
if data is None:
return None
node = TreeNode(data)
node.left = creat_tree(input_list)
node.right = creat_tree(input_list)
return node
input_list = [1, 2, 3, None, None, 4, None, None, 5, None, 6]
root = creat_tree(input_list)
方法二:层序创建
class TreeNode(object):
def __init__(self, data):
self.val = data
self.left = None
self.right = None
class BTree(object):
def __init__(self, root=None):
self.root = root
def add(self, item):
‘’‘添加节点’‘’
node = TreeNode(item)
if self.root is None:
self.root = node
return
q = [self.root]
while q:
cur_node = q.pop(0)
if cur_node.left is None:
cur_node.left = node
return
else:
q.append(cur_node.left)
if cur_node.right is None:
cur_node.right = node
return
else:
q.append(cur_node.right)
tree = BTree()
input_list = list(range(10))
while len(input_list) != 0:
data = input_list.pop(0)
tree.add(data)
print(tree.root)
遍历方式
方法一:递归遍历
class TreeNode(object):
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def create_binary_tree(input_list):
if input_list is None or len(input_list) == 0:
return None
data = input_list.pop(0)
if data is None:
return None
node = TreeNode(data)
node.left = create_binary_tree(input_list)
node.right = create_binary_tree(input_list)
return node
def pre_order(node):
'''先序遍历'''
if node is None:
return None
print(node.data, end=' ')
pre_order(node.left)
pre_order(node.right)
return node
def in_order(node):
‘’‘中序遍历’‘’
if node is None:
return None
in_order(node.left)
print(node.data, end=' ')
in_order(node.right)
return node
def back_order(node):
'''后序遍历'''
if node is None:
return None
back_order(node.left)
back_order(node.right)
print(node.data, end=' ')
return node
input_list = [1, 2, 3, None, None, 4, None, None, 5, None, 6]
root = create_binary_tree(input_list)
pre_order(input_list)
in_order(input_list)
back_order(input_list)
方法二:非递归遍历(栈)
class TreeNode(object):
def __init__(self, val):
self.val = val
self.left = None
self.right = None
class TreeTraverWithStack(object):
def create_tree(self, input_list):
if len(input_list) == 0 or input_list is None:
return
data = input_list.pop(0)
if data is None:
return None
node = TreeNode(data)
node.left = self.create_tree(input_list)
node.right = self.create_tree(input_list)
return node
def PreorderTranvel(self, head):
'''用栈实现二叉树先序遍历:放入栈的顺序是先右再左
'''
if head:
stack = [head]
while len(stack) > 0:
cur = stack.pop()
print(cur.val, end='\t')
if cur.right:
stack.append(cur.right)
if cur.left:
stack.append(cur.left)
def posOrderTranvel(self, head):
'''用栈实现后序遍历'''
if head:
stack1 = [head]
stack2 = []
while len(stack1) > 0:
cur = stack1.pop()
stack2.append(cur)
if cur.left:
stack1.append(cur.left)
if cur.right:
stack1.append(cur.right)
while stack2:
print(stack2.pop().val, end='\t')
def InorderTranvel(self, head):
if head:
stack = []
cur = head
while len(stack) > 0 or head:
if head:
# 如果左边界存在,一直把左边的节点压入栈
stack.append(head)
head = head.left
else:
# 如果左边界不存在了,弹出,从右开始看有无左边界
head = stack.pop()
print(head.val, end='\t')
head = head.right
def BroadTranvel(self, head):
'''宽度优先遍历'''
# 队列实现
from queue import Queue
q = Queue()
q.put(head)
while not q.empty():
cur = q.get()
print(cur.val, end='\t')
if cur.left:
q.put(cur.left)
if cur.right:
q.put(cur.right)
input_list = [1, 2, 3, None, None, 4, None, None, 5, 6, None, None, 7]
t = TreeTraverWithStack()
nodes = t.create_tree(input_list)
# 先序遍历
t.PreorderTranvel(nodes) # 1 2 3 4 5 6 7
print()
# 后序遍历
t.posOrderTranvel(nodes) # 3 4 2 6 7 5 1
print()
# 中序遍历
t.InorderTranvel(nodes) # 3 2 4 1 6 5 7
print()
# 宽度优先遍历
t.BroadTranvel(nodes) # 1 2 5 3 4 6 7