二叉树的层次遍历

题目描述:给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问)

样例:

二叉树的层次遍历_第1张图片

之前,我们已经学习了用非递归的解法解决二叉树的前序遍历,中序遍历,后序遍历。对于这三种深搜的策略,我采用了一种特殊的结构——栈。其实,我在之前也谈过,一般深搜可以用栈解决,而广搜,是可以用队列解决的,二叉树的层次遍历,就是一种典型的广度优先搜索。当然,关于广度优先搜索其实问题远不止层次遍历这么简单,这个以后会细讲。

看图,层次遍历的顺序在逻辑上是比较简单的,逐层遍历就行: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上还有一道二叉树层次遍历的题目,和这道题基本一样,不同之处在于,要求从底至顶输出,我的理解,实就是把上边的结果在二维数组内做一个翻转罢了,很简单。如果读者对从底至顶的层次遍历所要考察的知识点有不同的的认识,希望可以告诉我其。


你可能感兴趣的:(二叉树的层次遍历)