Easy | LeetCode 102 | 剑指 Offer 32

剑指 Offer 32 - II. 从上到下打印二叉树 II

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

例如:
给定二叉树: [3,9,20,null,null,15,7],

  3
 / 
9  20
  /  
 15   7

返回其层次遍历结果:

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

提示:

  1. 节点总数 <= 1000

方法一: 双队列

使用两个队列实现, 一个队列用于遍历本层的节点, 另一个队列用于存放下一层的节点。

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> res = new ArrayList<>();
    if (root == null) {
        return res;
    }
    // 定义两个队列, 分别用于遍历本层的节点 和 存放 下一层的节点
    Deque<TreeNode> queue1 = new ArrayDeque<TreeNode>();
    Deque<TreeNode> queue2 = new ArrayDeque<TreeNode>();
    
    queue1.addLast(root);
    
    // 只要有队列非空就要继续遍历
    while (!queue1.isEmpty() || !queue2.isEmpty()) {
        
        // 用于存放本层的结果
        List<Integer> curRes = new ArrayList<>();
        while (!queue1.isEmpty()) {
            // 将队列1的元素逐个出队
            TreeNode node = queue1.removeFirst();
            curRes.add(node.val);
            if (node.left != null) {
                // 将出队元素的左右孩子入队到队列2
                queue2.addLast(node.left);
            }
            if (node.right != null) {
                queue2.addLast(node.right);
            }
        }
        if (curRes.size() > 0) {
            res.add(curRes);
        }

        // 用于放置本层遍历的结果
        curRes = new ArrayList<>();
        // 如果队列2有元素 就将其出队遍历
        while (!queue2.isEmpty()) {
            TreeNode node = queue2.removeFirst();
            curRes.add(node.val);
            if (node.left != null) {
                // 将其孩子添加对另个一队列 队列1
                queue1.addLast(node.left);
            }
            if (node.right != null) {
                queue1.addLast(node.right);
            }
        }
        // 在这里CurRes是有可能没有元素的, 因为上次队列1的元素可能就是数的最后一层
        if (curRes.size() > 0) {
            res.add(curRes);
        }
    }
    return res;
}

方法二

可以只使用一个队列, 通过统计每层元素的个数来实现对各个层的控制

public List<List<Integer>> levelOrder(TreeNode root) {
    Queue<TreeNode> queue = new LinkedList<>();
    List<List<Integer>> res = new ArrayList<>();
    if(root != null) queue.add(root);
    while(!queue.isEmpty()) {
        List<Integer> tmp = new ArrayList<>();
        // 在while的每一轮循环开始的时间, 计算队列的大小
       	// 这个大小就是本层元素的个数
        // 在这里先对本层所有元素出队, 同时将其孩子入队
        for(int i = queue.size(); i > 0; i--) {
            TreeNode node = queue.poll();
            tmp.add(node.val);
            if(node.left != null) queue.add(node.left);
            if(node.right != null) queue.add(node.right);
        }
        // for循环结束之后, 队列的元素就恰好是下一层的所有元素
        res.add(tmp);
    }
    return res;
}
原文地址:https://www.cnblogs.com/chenrj97/p/14285667.html