树(tree)是一种非线性的数据结构,是一种抽象数据类型(ADT),用来模拟具有树状结构性质的数据集合,它是由n(n>0)个有限节点通过连接它们的边组成一个具有层次关系的集合。
树的结构十分直观,而树的很多概念定义都有一个相同的特点:递归,也就是说,一棵树要满足某种性质,往往要求每个节点都必须满足。
例如,在定义一棵二叉搜索树时,每个节点也都必须是一棵二叉搜索树。
class Empty(Exception):
pass
class ParamsError(Exception):
pass
class Stack(object):
"""模拟栈"""
def __init__(self):
self._data = []
def __len__(self):
return len(self._data)
def is_empty(self):
"""Return True if the stack is empty."""
return len(self._data) == 0
def pop(self):
"""Remove and return the element from the top of the stack."""
if self.is_empty():
raise Empty('Stack is empty.')
return self._data.pop()
def push(self, e):
"""Add an element e to the top of the stack."""
self._data.append(e)
def top(self):
"""Return the element at the top of the stack."""
if self.is_empty():
raise Empty('Stack is empty.')
return self._data[-1]
class Queue(object):
"""模拟队列"""
def __init__(self):
self._data = []
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return self._size == 0
def first(self):
if self.is_empty():
raise Empty('Queue is empty.')
return self._data[0]
def dequeue(self):
if self.is_empty():
raise Empty('Queue is empty.')
self._size -= 1
return self._data.pop(0)
def enqueue(self, e):
self._data.append(e)
self._size += 1
class Node(object):
"""节点"""
def __init__(self, data=None, left=None, right=None):
self.data = data
self.left = left
self.right = right
class Tree(object):
"""创建树"""
default_chars = [chr(c) for c in range(65, 91)]
def __init__(self, seq=None, depth=4, is_complete=True):
"""
初始化
:param seq: 二叉树元素序列
:param depth: 深度
:param is_complete: 是否为完全二叉树
"""
seq = self.default_chars if seq is None else seq
if len(seq) < depth and is_complete:
raise ParamsError('seq is too small or depth is too large!')
self.depth = depth
self._root = None
self.chars = seq[:pow(2, self.depth) - 1] if is_complete else seq
def create(self):
"""执行创建"""
# tree = self._recursive_create_node(self.chars)
# 生成完全二叉树
for (i, j) in enumerate(self.chars):
node = Node(j)
if i == 0:
self._root = node
else:
self._insert_node(node)
return self._root
def _recursive_create_node(self, seq):
"""递归创建节点"""
n = len(seq)
if n == 0:
return None
i = n // 2
return Node(seq[i], self._recursive_create_node(seq[:i]), self._recursive_create_node(seq[i + 1:]))
def _insert_node(self, node):
# 建立一个完全二叉树
lst = []
def _insert(tree_node, p, node):
if tree_node.left is None:
tree_node.left = node
lst.append(tree_node.left)
return
elif tree_node.right is None:
tree_node.right = node
lst.append(tree_node.right)
return
else:
lst.append(tree_node.left)
lst.append(tree_node.right)
if p > (len(lst) - 2):
return
else:
_insert(lst[p + 1], p + 1, node)
lst.append(self._root)
_insert(self._root, 0, node)
二叉树的遍历有:深度遍历和广度遍历,深度遍历分为:前序、中序以及后序三种遍历方法,广度遍历即层次遍历。
其中深度遍历可以利用 栈 的结构来实现,广度遍历可以利用 队列 的结构来实现。
import sys
class Tree(object):
"""二叉树"""
@staticmethod
def pre_traversal(tree):
"""深度遍历 - 前序遍历: 栈实现 (根->左->右)"""
if tree is None:
return
data_list = []
stack = Stack()
stack.push(tree) # 根入栈
while not stack.is_empty():
node = stack.pop() # 出栈
data_list.append(str(node.data))
if node.right:
stack.push(node.right) # 右节点入栈
if node.left:
stack.push(node.left)
sys.stdout.write('前序遍历: ' + '->'.join(data_list))
def pre_order(tree, lst=[]):
"""前序遍历: 根->左->右"""
if tree is None:
return
# print(tree.data, end='->')
lst.append(tree.data)
self.pre_order(tree.left, lst)
self.pre_order(tree.right, lst)
return lst
class Tree(object):
"""二叉树"""
@staticmethod
def in_traversal(tree):
"""深度遍历 - 中序遍历: 栈实现 (左->根->右)"""
if tree is None:
return
data_list = []
stack = Stack()
node = tree
while node or not stack.is_empty():
while node: # 循环查找左节点
stack.push(node)
node = node.left
# 循环结束,表示左节点为空
node = stack.pop() # 左节点,从下往上
data_list.append(str(node.data))
node = node.right # 上一个左节点的右子节点
sys.stdout.write('中序遍历: ' + '->'.join(data_list))
def mid_order(tree, lst=[]):
"""中序遍历: 左->根->右"""
if tree is None:
return
self.mid_order(tree.left, lst)
# print(tree.data, end='->')
lst.append(tree.data)
self.mid_order(tree.right, lst)
return lst
class Tree(object):
"""二叉树"""
@staticmethod
def post_traversal(tree):
"""深度遍历 - 后序遍历: 栈实现 (左->右->根)"""
if tree is None:
return
data_list = []
stack1 = Stack()
stack2 = Stack()
node = tree
stack1.push(node)
while not stack1.is_empty(): # stack1 存放遍历的逆序,正确顺序放入 stack2 中
node = stack1.pop()
if node.left:
stack1.push(node.left)
if node.right:
stack1.push(node.right)
stack2.push(node)
while not stack2.is_empty():
data_list.append(str(stack2.pop().data))
sys.stdout.write('后序遍历: ' + '->'.join(data_list))
def post_order(tree, lst=[]):
"""后序遍历: 左->右->根"""
if tree is None:
return
self.post_order(tree.left, lst)
self.post_order(tree.right, lst)
# print(tree.data, end='->')
lst.append(tree.data)
return lst
class Tree(object):
"""二叉树"""
@staticmethod
def level_traversal(tree):
"""广度遍历: 层次遍历 - 队列实现"""
if tree is None:
return
data_list = []
queue = Queue()
node = tree
queue.enqueue(node)
while not queue.is_empty():
node = queue.dequeue() # 出队
data_list.append(str(node.data))
if node.left:
queue.enqueue(node.left) # 左节点入队
if node.right:
queue.enqueue(node.right)
sys.stdout.write('广度遍历: ' + '->'.join(data_list))
def code_test():
"""测试"""
# tree = Tree(depth=3)
# tree = Tree(seq=[i for i in range(1, 10)], depth=3)
tree = Tree(seq=[i for i in range(1, 10)], is_complete=False)
btree = tree.create()
# 深度遍历
# 1-前序遍历
print(pre_order(btree)) # [1, 2, 4, 8, 9, 5, 3, 6, 7]
tree.pre_traversal(btree) # 前序遍历: 1->2->4->8->9->5->3->6->7
print('\n----------------------------------------')
# 2-中序遍历
print(mid_order(btree)) # [8, 4, 9, 2, 5, 1, 6, 3, 7]
tree.in_traversal(btree) # 中序遍历: 8->4->9->2->5->1->6->3->7
print('\n----------------------------------------')
# 3-后序遍历
print(post_order(btree)) # [8, 9, 4, 5, 2, 6, 7, 3, 1]
tree.post_traversal(btree) # 后序遍历: 8->9->4->5->2->6->7->3->1
print('\n----------------------------------------')
# 广度遍历
tree.level_traversal(btree) # 广度遍历: 1->2->3->4->5->6->7->8->9
print('\n----------------------------------------')
if __name__ == '__main__':
code_test()