Leetcode - Binary Tree Level Order Traversal

Question

Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).

For example:
Given binary tree {3,9,20,#,#,15,7},

  3
 / \
9  20
   / \
 15   7

return its level order traversal as:

[ 
 [3], 
 [9,20],
 [15,7] 
]

OJ’s Binary Tree Serialization:

The serialization of a binary tree follows a level order traversal, where ‘#’ signifies a path terminator where no node exists below.

Here’s an example:

  1
 / \
2   3
   /
  4
   \
    5

The above binary tree is serialized as “{1,2,3,#,#,4,#,#,5}”.


Java Code

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public List<List<Integer>> levelOrder(TreeNode root) {
    LinkedList<List<Integer>> nodes = new LinkedList<List<Integer>>();//存储所有层节点的val
    LinkedList<TreeNode> list = new LinkedList<>();//节点队列,存储当前遍历的层的所有节点

    //若输入为空树,则返回空的nodes
    if(root == null) return nodes;

    //将根节点root和层标志位null入队
    list.add(root);
    list.add(null);

    //将根节点的val保存到nodes的第一个List集合中
    List<Integer> levelNodes = new LinkedList<Integer>();
    levelNodes.add(root.val);
    nodes.add(levelNodes);

    TreeNode temp, Left, Right;

    //如果队列中不是仅剩标志位一个元素
    while(list.size() != 1) {
        //遍历二叉树新的一层,先new一个List并添加到nodes中,用于保存当前层的节点值
        levelNodes = new LinkedList<Integer>();
        nodes.add(levelNodes);
        //通过出队依次访问当前层所有节点得到对应的子节点,直到遇到层标志位null
        while ((temp = list.poll()) != null) {
            if((Left = temp.left) != null) {
                list.add(Left);//当前节点的左子节点入队
                levelNodes.add(Left.val);//保存节点的val
            }

            if((Right = temp.right) != null) {
                list.add(Right);//当前节点的右子节点入队
                levelNodes.add(Right.val);
            }
        }
        //已遍历完一层,在队尾设置新的层标志位
        list.add(null);
    }

    //最后一次层次遍历没有节点
    nodes.removeLast();

    return nodes;
}

说明

  • 二叉树的层次遍历使用广度优先搜索算法(BFS,breadth-first search),一般通过队列或链表实现。从根节点开始,每一层的节点依次入队,层与层之间设置隔离标志位(null),然后按照先进先出的规则,每一层依次出队,每个节点出队的同时,获取其左右子节点,并依次入队,同时保存节点的val,从而能够取出二叉树中每一层的节点。

更新

2016.05.03

  • 下面以问题中给的二叉树为例,简述代码的执行逻辑:
    内层while循环开始之前,各个变量为

    list         [null, node3]  
    levelNodes   [3]
    nodes        [3]
    

    进入第一次while循环,先给nodes添加一个空的List,即levelNodes

    levelNodes   [3]
    nodes        [[3], []]
    

    然后list的第一个元素(节点node3)出队,得到其左右两个子节点,并依次从list的尾部入队,同时保存这两个子节点的val到nodes的空List中,得到

    list         [node20, node9, null]
    levelNodes   [9, 20]
    nodes        [[3], [9, 20]]
    

    然后list的第二个元素(null)出队,它就是第一层节点结束的标志位,则第一层所有节点已经遍历完,内层while循环结束,此时list中存放的就是第二层的所有节点了,我们在其尾部将null入队,作为第二层的结束标志位。则第二次while循环开始之前,各个变量为

    list         [null, node20, node9]
    levelNodes   []
    nodes        [[3], [9, 20]]
    

    然后重复上述步骤,依次将list中的元素出列,得到第三层的节点并将它们入列。当内层while完成第三次循环后,list只剩下层标志位null了,此时外层的while循环判断为假,结束所有循环,注意最后一次我们往nodes中添加了一个空list,所以return之前要删除它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值