# 定义二叉树结点
class Node(object):
"""定义结点"""
def __init__(self, item):
self.elem = item
self.lchild = None
self.rchild = None
# 定义二叉树
class Tree(object):
"""二叉树"""
def __init__(self):
self.root = None
# 添加树结点
def add(self, item):
node = Node(item)
if self.root is None:
self.root = node
return
queue = []
queue.append(self.root)
while queue:
cur_node = queue.pop(0)
if cur_node.lchild is None:
cur_node.lchild = node
return
else:
queue.append(cur_node.lchild)
if cur_node.rchild is None:
cur_node.rchild = node
return
else:
queue.append(cur_node.rchild)
def breadth_travel(self):
"""广度优先遍历:借助队列实现"""
if self.root is None:
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
print(cur_node.elem)
if cur_node.lchild is not None:
queue.append(cur_node.lchild)
if cur_node.rchild is not None:
queue.append(cur_node.rchild)
深度优先遍历包括三种情况:
# 递归实现
def preorder(self, root):
if root == None:
return
print(root.elem)
self.preorder(root.lchild)
self.preorder(root.rchild)
# 非递归实现
def preorder(self, root):
"""通过栈实现"""
stack = [] # 用于保存访问路径,使算法能够回溯
cur_node = root
while cur_node or stack:
if cur_node:
print(cur_node.elem)
stack.append(cur_node) # 保存访问过的结点
cur_node = cur_node.lchild
else: # 开始回溯
cur_node = stack.pop()
cur_node = cur_node.rchild
# 递归实现
def inorder(self, root):
if root == None:
return
self.inorder(root.lchild)
print(root.elem)
self.inorder(root.rchild)
# 非递归实现
def inorder(self, root):
"""通过栈实现"""
stack = [] # 用于保存访问路径,使算法能够回溯
cur_node = root
while cur_node or stack:
if cur_node:
stack.append(cur_node) # 保存路径
cur_node = cur_node.lchild
else: # 开始回溯
cur_node = stack.pop()
print(cur_node.elem)
cur_node = cur_node.rchild
# 递归实现
def postorder(self, root):
if root == None:
return
self.postorder(root.lchild)
self.postorder(root.rchild)
print(root.elem)
def postorder(self, root):
"""通过栈实现"""
stack = [] # 用于保存访问路径,使算法能够回溯
flag = [] # 用于记录路径经过结点的次数,控制访问结点的时机
cur_node = root
while cur_node or stack:
if cur_node:
stack.append(cur_node) # 保存路径
flag.append(1) # 记录第一次经过该结点,开始访问左子树
cur_node = cur_node.lchild
else: # 开始回溯
cur_node = stack.pop()
f = flag.pop()
if f == 1: # 经过该结点一次,左子树已访问完
stack.append(cur_node)
flag.append(2) # 记录第二次经过该结点,开始访问右子树
cur_node = cur_node.rchild
else: # f == 2 两棵子树访问完,开始访问父结点
print(cur_node.elem)
cur_node = None
"""
这里不是 cur_node == stack.pop() 是因为子树全部访问完,
要进入回溯过程,取出路径中保存的最后一个标志进行判断
若是从左子树进行的回溯,则访问右子树
若是从右子树进行的回溯,则访问父结点
"""