问题:实现一个函数,输入二叉树,从上往下打印出二叉树的每个结点,同一层的结点按从左到右的顺序打印。
这道题有别于前序、中序、后序遍历二叉树的方法,该题是按层遍历二叉树。
原理:
不难理解,使用一个辅助空间,FIFO容器可以解决该问题。当遍历根结点后,分别把根结点的左右子树的根结点放到队列容器中。由于队列有FIFO特性,下次从队列中取出的元素一定是左子树的根结点。类似地,左子树的根结点的孩子元素也在遍历时放到队列中…以此类推。队列确保元素按层次排序。
实现:
先实现一个简单的队列做容器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Queue: def __init__(self): self._q = []
def put(self, item): self._q.append(item)
def get(self): item = self._q[0] del self._q[0] return item
def empty(self): return len(self._q) == 0
|
建立一颗二叉树,用于做测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Node: def __init__(self, value): self.value = value self.left = None self.right = None
def __repr__(self): return "Node<{}>".format(self.value)
root = Node(8) root.left = Node(6) root.right = Node(10)
root.left.left = Node(5) root.left.right = Node(7)
root.right.left = Node(9) root.right.right = Node(11)
|
实现按层遍历二叉树函数。
1 2 3 4 5 6 7 8 9 10 11 12 13
| def print_tree_from_top_to_bottom(root): queue = Queue() queue.put(root) while not queue.empty(): node = queue.get() print(node) if node.left: queue.put(node.left) if node.right: queue.put(node.right)
if __name__ == '__main__': print_tree_from_top_to_bottom(root)
|
输出结果:
1 2 3 4 5 6 7
| Node<8> Node<6> Node<10> Node<5> Node<7> Node<9> Node<11>
|
如果打印的输出形式也是分层,我们稍作处理即可。
如果我们需要树一其自身结构分层打印,可以做如下处理。通过标记层的结点数可以解决。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import collections
def print_tree_step(tree): stack = collections.deque() stack.append(tree) next_level_count = 0 current_print_count = 1
while len(stack): p_node = stack.popleft() print(p_node, end='\t') current_print_count -= 1 if p_node.left is not None: next_level_count += 1 stack.append(p_node.left) if p_node.right is not None: next_level_count += 1 stack.append(p_node.right) if current_print_count == 0: current_print_count = next_level_count next_level_count = 0 print('\n')
|
这正是我们期待的结果。
启发地,如果要建立一颗二叉树,根据输入序列,按层级建立:从上往下,从左到右。也用类似的思路。