聊聊从上到下打印二叉树

开发 前端
最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N) 大小的额外空间。

 [[438363]]

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],

  1.      3 
  2.     / \ 
  3.   9  20 
  4.  /  \ 
  5. 15   7 

返回:

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

提示:节点总数 <= 1000

解题思路:

  • 题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 广度优先搜索(BFS)。
  • BFS 通常借助 队列 的先入先出特性来实现。

算法流程:

  • 特例处理: 当树的根节点为空,则直接返回空列表 [] ;
  • 初始化: 打印结果列表 res = [] ,包含根节点的队列 queue = [root] ;
  • BFS 循环: 当队列 queue 为空时跳出;
    • 出队: 队首元素出队,记为 node;
    • 打印: 将 node.val 添加至列表 tmp 尾部;
    • 添加子节点: 若 node 的左(右)子节点不为空,则将左(右)子节点加入队列 queue ;
  • 返回值: 返回打印结果列表 res 即可。

复杂度分析:

  1. 时间复杂度 O(N): N为二叉树的节点数量,即 BFS 需循环 N次。
  2. 空间复杂度 O(N) :最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N) 大小的额外空间。
  1. package com.nateshao.sword_offer.topic_25_levelOrder; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.LinkedList; 
  5. import java.util.Queue; 
  6. /** 
  7.  * @date Created by 邵桐杰 on 2021/11/29 14:57 
  8.  * @微信公众号 程序员千羽 
  9.  * @个人网站 www.nateshao.cn 
  10.  * @博客 https://nateshao.gitee.io 
  11.  * @GitHub https://github.com/nateshao 
  12.  * @Gitee https://gitee.com/nateshao 
  13.  * Description: 从上到下打印二叉树 思路:利用队列(链表)辅助实现。 
  14.  * 
  15.  * add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常 
  16.  * remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常 
  17.  * element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常 
  18.  * offer 添加一个元素并返回true 如果队列已满,则返回false 
  19.  * poll 移除并返问队列头部的元素 如果队列为空,则返回null 
  20.  * peek 返回队列头部的元素 如果队列为空,则返回null 
  21.  * put 添加一个元素 如果队列满,则阻塞 
  22.  * take 移除并返回队列头部的元素 如果队列为空,则阻塞 
  23.  */ 
  24. public class Solution { 
  25.  
  26.     /** 
  27.      *  队列 
  28.      * 
  29.      * @param root 
  30.      * @return 
  31.      */ 
  32.     public int[] levelOrder(TreeNode root) { 
  33.         if (root == nullreturn new int[0];//空树则返回空数组 
  34.         ArrayList<Integer> list = new ArrayList<>();// 申请一个动态数组 ArrayList 动态添加节点值 
  35.         Queue<TreeNode> queue = new LinkedList<>(); 
  36.         queue.offer(root);// 根结点先入队 
  37.         while (!queue.isEmpty()) { 
  38.             TreeNode node = queue.poll();// 取出当前队首元素 
  39.             list.add(node.val); 
  40.             if (node.left != null) queue.offer(node.left);// 左子节点入队 
  41.             if (node.right != null) queue.offer(node.right);// 右子节点入队 
  42.         } 
  43.         // 将 ArrayList 转为 int数组并返回 
  44.         int[] res = new int[list.size()]; 
  45.         for (int i = 0; i < res.length; i++) { 
  46.             res[i] = list.get(i); 
  47.         } 
  48.         return res; 
  49.     } 
  50.  
  51.     /************ 递归 *************/ 
  52.     public ArrayList<Integer> PrintFromTopToBottom2(TreeNode root) { 
  53.         ArrayList<Integer> list = new ArrayList<Integer>(); 
  54.         if (root == null) { 
  55.             return list; 
  56.         } 
  57.         list.add(root.val); 
  58.         levelOrder(root, list); 
  59.         return list; 
  60.     } 
  61.     public void levelOrder(TreeNode root, ArrayList<Integer> list) { 
  62.         if (root == null) { 
  63.             return
  64.         } 
  65.         if (root.left != null) { 
  66.             list.add(root.left.val); 
  67.         } 
  68.         if (root.right != null) { 
  69.             list.add(root.right.val); 
  70.         } 
  71.         levelOrder(root.left, list); 
  72.         levelOrder(root.right, list); 
  73.     } 
  74.  
  75.     public class TreeNode { 
  76.         int val; 
  77.         TreeNode left
  78.         TreeNode right
  79.  
  80.         TreeNode(int x) { 
  81.             val = x; 
  82.         } 
  83.     } 

从上到下打印二叉树 II

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

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

  1.      3 
  2.     / \ 
  3.    9  20 
  4.  /  \ 
  5. 15   7 

返回其层次遍历结果:

  1.   [3], 
  2.   [9,20], 
  3.   [15,7] 

  1. public List<List<Integer>> levelOrder(TreeNode root) { 
  2.         Queue<TreeNode> queue = new LinkedList<>(); 
  3.         List<List<Integer>> res = new ArrayList<>(); 
  4.         if(root != null) queue.add(root); 
  5.         while(!queue.isEmpty()) { 
  6.             List<Integer> tmp = new ArrayList<>(); 
  7.             for(int i = queue.size(); i > 0; i--) { 
  8.                 TreeNode node = queue.poll(); 
  9.                 tmp.add(node.val); 
  10.                 if(node.left != null) queue.add(node.left); 
  11.                 if(node.right != null) queue.add(node.right); 
  12.             } 
  13.             res.add(tmp); 
  14.         } 
  15.         return res; 

III. 从上到下打印二叉树 III

“题目描述: 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。例如: 给定二叉树: [3,9,20,null,null,15,7],

  1.   3 
  2.  / \ 
  3. 9  20 
  4.   /  \ 
  5.  15   7 

返回其层次遍历结果:

  1.   [3], 
  2.   [20,9], 
  3.   [15,7] 
  1. class Solution { 
  2.     public List<List<Integer>> levelOrder(TreeNode root) { 
  3.         Deque<TreeNode> deque = new LinkedList<>(); 
  4.         List<List<Integer>> res = new ArrayList<>(); 
  5.         if(root != null) deque.add(root); 
  6.         while(!deque.isEmpty()) { 
  7.             // 打印奇数层 
  8.             List<Integer> tmp = new ArrayList<>(); 
  9.             for(int i = deque.size(); i > 0; i--) { 
  10.                 // 从左向右打印 
  11.                 TreeNode node = deque.removeFirst(); 
  12.                 tmp.add(node.val); 
  13.                 // 先左后右加入下层节点 
  14.                 if(node.left != null) deque.addLast(node.left); 
  15.                 if(node.right != null) deque.addLast(node.right); 
  16.             } 
  17.             res.add(tmp); 
  18.             if(deque.isEmpty()) break; // 若为空则提前跳出 
  19.             // 打印偶数层 
  20.             tmp = new ArrayList<>(); 
  21.             for(int i = deque.size(); i > 0; i--) { 
  22.                 // 从右向左打印 
  23.                 TreeNode node = deque.removeLast(); 
  24.                 tmp.add(node.val); 
  25.                 // 先右后左加入下层节点 
  26.                 if(node.right != null) deque.addFirst(node.right); 
  27.                 if(node.left != null) deque.addFirst(node.left); 
  28.             } 
  29.             res.add(tmp); 
  30.         } 
  31.         return res; 
  32.     } 

参考连接:

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

责任编辑:武晓燕 来源: 程序员千羽
相关推荐

2020-04-27 07:05:58

二叉树左子树右子树

2021-10-12 09:25:11

二叉树树形结构

2021-11-28 23:54:28

子树B结构

2024-05-22 09:23:03

CSSgrid布局前端

2021-04-19 07:47:42

数据结构二叉树Tree

2021-04-20 08:37:14

数据结构二叉树

2013-07-15 16:35:55

二叉树迭代器

2021-03-17 08:19:22

二叉树LeetCode

2023-02-01 07:27:46

序列化二叉树根节点

2021-09-29 10:19:00

算法平衡二叉树

2020-09-23 18:25:40

算法二叉树多叉树

2021-04-28 20:12:27

数据结构创建

2022-10-26 23:58:02

二叉树数组算法

2021-05-06 17:46:30

二叉树数据结构

2023-05-08 15:57:16

二叉树数据结构

2021-03-22 08:23:29

LeetCode二叉树节点

2021-08-27 11:36:44

二叉树回溯节点

2018-03-15 08:31:57

二叉树存储结构

2021-12-17 14:26:58

二叉树节点数量

2021-07-13 14:03:24

二叉树满二叉树完全二叉树
点赞
收藏

51CTO技术栈公众号