Leetcode :
- I:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof
- II:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof
- III:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof
“GitHub : https://github.com/nateshao/leetcode/blob/main/algo-notes/src/main/java/com/nateshao/sword_offer/topic_25_levelOrder/Solution.java
从上到下打印二叉树 I
“题目描述 :从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。例如:给定二叉树: [3,9,20,null,null,15,7],
- 3
- / \
- 9 20
- / \
- 15 7
返回:
- [3,9,20,15,7]
提示:节点总数 <= 1000
解题思路:
- 题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 广度优先搜索(BFS)。
- BFS 通常借助 队列 的先入先出特性来实现。
算法流程:
- 特例处理: 当树的根节点为空,则直接返回空列表 [] ;
- 初始化: 打印结果列表 res = [] ,包含根节点的队列 queue = [root] ;
- BFS 循环: 当队列 queue 为空时跳出;
- 出队: 队首元素出队,记为 node;
- 打印: 将 node.val 添加至列表 tmp 尾部;
- 添加子节点: 若 node 的左(右)子节点不为空,则将左(右)子节点加入队列 queue ;
- 返回值: 返回打印结果列表 res 即可。
复杂度分析:
- 时间复杂度 O(N): N为二叉树的节点数量,即 BFS 需循环 N次。
- 空间复杂度 O(N) :最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N) 大小的额外空间。
- package com.nateshao.sword_offer.topic_25_levelOrder;
- import java.util.ArrayList;
- import java.util.LinkedList;
- import java.util.Queue;
- /**
- * @date Created by 邵桐杰 on 2021/11/29 14:57
- * @微信公众号 程序员千羽
- * @个人网站 www.nateshao.cn
- * @博客 https://nateshao.gitee.io
- * @GitHub https://github.com/nateshao
- * @Gitee https://gitee.com/nateshao
- * Description: 从上到下打印二叉树 思路:利用队列(链表)辅助实现。
- *
- * add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
- * remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
- * element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
- * offer 添加一个元素并返回true 如果队列已满,则返回false
- * poll 移除并返问队列头部的元素 如果队列为空,则返回null
- * peek 返回队列头部的元素 如果队列为空,则返回null
- * put 添加一个元素 如果队列满,则阻塞
- * take 移除并返回队列头部的元素 如果队列为空,则阻塞
- */
- public class Solution {
- /**
- * 队列
- *
- * @param root
- * @return
- */
- public int[] levelOrder(TreeNode root) {
- if (root == null) return new int[0];//空树则返回空数组
- ArrayList<Integer> list = new ArrayList<>();// 申请一个动态数组 ArrayList 动态添加节点值
- Queue<TreeNode> queue = new LinkedList<>();
- queue.offer(root);// 根结点先入队
- while (!queue.isEmpty()) {
- TreeNode node = queue.poll();// 取出当前队首元素
- list.add(node.val);
- if (node.left != null) queue.offer(node.left);// 左子节点入队
- if (node.right != null) queue.offer(node.right);// 右子节点入队
- }
- // 将 ArrayList 转为 int数组并返回
- int[] res = new int[list.size()];
- for (int i = 0; i < res.length; i++) {
- res[i] = list.get(i);
- }
- return res;
- }
- /************ 递归 *************/
- public ArrayList<Integer> PrintFromTopToBottom2(TreeNode root) {
- ArrayList<Integer> list = new ArrayList<Integer>();
- if (root == null) {
- return list;
- }
- list.add(root.val);
- levelOrder(root, list);
- return list;
- }
- public void levelOrder(TreeNode root, ArrayList<Integer> list) {
- if (root == null) {
- return;
- }
- if (root.left != null) {
- list.add(root.left.val);
- }
- if (root.right != null) {
- list.add(root.right.val);
- }
- levelOrder(root.left, list);
- levelOrder(root.right, list);
- }
- public class TreeNode {
- int val;
- TreeNode left;
- TreeNode right;
- TreeNode(int x) {
- val = x;
- }
- }
- }
从上到下打印二叉树 II
题目描述 :从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
“例如:给定二叉树: [3,9,20,null,null,15,7],
- 3
- / \
- 9 20
- / \
- 15 7
返回其层次遍历结果:
- [
- [3],
- [9,20],
- [15,7]
- ]
- 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<>();
- 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);
- }
- res.add(tmp);
- }
- return res;
- }
III. 从上到下打印二叉树 III
“题目描述: 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。例如: 给定二叉树: [3,9,20,null,null,15,7],
- 3
- / \
- 9 20
- / \
- 15 7
返回其层次遍历结果:
- [
- [3],
- [20,9],
- [15,7]
- ]
- class Solution {
- public List<List<Integer>> levelOrder(TreeNode root) {
- Deque<TreeNode> deque = new LinkedList<>();
- List<List<Integer>> res = new ArrayList<>();
- if(root != null) deque.add(root);
- while(!deque.isEmpty()) {
- // 打印奇数层
- List<Integer> tmp = new ArrayList<>();
- for(int i = deque.size(); i > 0; i--) {
- // 从左向右打印
- TreeNode node = deque.removeFirst();
- tmp.add(node.val);
- // 先左后右加入下层节点
- if(node.left != null) deque.addLast(node.left);
- if(node.right != null) deque.addLast(node.right);
- }
- res.add(tmp);
- if(deque.isEmpty()) break; // 若为空则提前跳出
- // 打印偶数层
- tmp = new ArrayList<>();
- for(int i = deque.size(); i > 0; i--) {
- // 从右向左打印
- TreeNode node = deque.removeLast();
- tmp.add(node.val);
- // 先右后左加入下层节点
- if(node.right != null) deque.addFirst(node.right);
- if(node.left != null) deque.addFirst(node.left);
- }
- res.add(tmp);
- }
- return res;
- }
- }
参考连接:
https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/solution/mian-shi-ti-32-i-cong-shang-dao-xia-da-yin-er-ch-4
https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/solution/mian-shi-ti-32-ii-cong-shang-dao-xia-da-yin-er-c-5
https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/solution/mian-shi-ti-32-iii-cong-shang-dao-xia-da-yin-er--3