题目描述:给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问)
样例:
之前,我们已经学习了用非递归的解法解决二叉树的前序遍历,中序遍历,后序遍历。对于这三种深搜的策略,我采用了一种特殊的结构——栈。其实,我在之前也谈过,一般深搜可以用栈解决,而广搜,是可以用队列解决的,二叉树的层次遍历,就是一种典型的广度优先搜索。当然,关于广度优先搜索其实问题远不止层次遍历这么简单,这个以后会细讲。
看图,层次遍历的顺序在逻辑上是比较简单的,逐层遍历就行:ABCDEFG
根据队列先进先出的性质,层次遍历用队列就特别简单了。下面我来介绍两种方法,分别使用一个及两个队列。
方法一:使用两个队列
这个比较简单,设置两个队列cur_list,next_list分别存储当前需处理的层的节点以及下一层的节点,拿这幅图来说
1. 先令cur_list存储根节点A,cur_list = [A]
2. 令cur_list中的节点依次出队列,将出队列的节点所存储的值添加到一个空列表level中,此时,level = [A]
3. 将这个被处理节点(A)的左右孩子(如果有的话)依次添加到next_list中,此时next_list = [B,C]
4. 当cur_list为空时(因为不断有节点处队列),交换cur_list与next_list,同时记录下level的值,令level为空,继续进入下一轮循环,处理下一层节点。
逻辑相当简单,可以轻松写出代码:
"""
Definition of TreeNode:
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
"""
class Solution:
"""
@param root: The root of binary tree.
@return: Level order in a list of lists of integers
"""
def levelOrder(self, root):
result = []
cur_list = []
if root:
cur_list = [root]
next_list = []
# level用来保存每一层的元素
level = []
# 第一步是按层循环
while len(cur_list) != 0:
# 对每一层的所有元素遍历
while len(cur_list) != 0:
# 删除队首
temp = cur_list.pop(0)
level.append(temp.val)
# 将下一层的树节点插入next_list
if temp.left:
next_list.append(temp.left)
if temp.right:
next_list.append(temp.right)
result.append(level)
# 交换两个list
cur_list, next_list = next_list, []
level = []
return result
# write your code here
一个队列的问题核心在于我不知道这一层到底有几个节点,如果不是输出一个二维矩阵的遍历结果,每一行代表一层的话,这个问题就简单了。
现在怎么解决呢,其实有一种很笨,同时也是很简单的方法,那就是使用两个整型的变量,记录当前层以及下一层的节点个数,这样,我就能知道我需要在这一行输出几个值了。
基本思路还是方法一所给出的,稍微修改一下代码就行
"""
Definition of TreeNode:
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
"""
class Solution:
"""
@param root: The root of binary tree.
@return: Level order in a list of lists of integers
"""
def levelOrder(self, root):
result = []
if root is None:
return result
cur_list = [root]
level = []
# 初始化cur_count = 1,因为已经存了根节点
cur_count, next_count = 1, 0
while len(cur_list) != 0:
# 循环条件:当前这一层还没处理完
while cur_count != 0:
temp = cur_list.pop(0)
level.append(temp.val)
cur_count = cur_count - 1
if temp.left:
cur_list.append(temp.left)
next_count = next_count + 1
if temp.right:
cur_list.append(temp.right)
next_count = next_count + 1
cur_count = next_count
next_count = 0
result.append(level)
level = []
return result
# write your code here
其中,cur_count代表当前这一层还需处理的节点的个数,而next_count代表下一层的节点数(从0开始,逐步加一得到的)
LintCode上还有一道二叉树层次遍历的题目,和这道题基本一样,不同之处在于,要求从底至顶输出,我的理解,实就是把上边的结果在二维数组内做一个翻转罢了,很简单。如果读者对从底至顶的层次遍历所要考察的知识点有不同的的认识,希望可以告诉我其。