前言

大家好,我是bigsai,在数据结构与算法中,二叉树无论是考研、笔试都是非常高频的考点内容,在二叉树中,二叉树的遍历又是非常重要的知识点,今天给大家讲讲二叉树的层序遍历。

这部分很多人可能会但是需要注重一下细节。

前面介绍了二叉排序树的构造和基本方法的实现,遍历也是比较重要的一环,并且二叉树的层序遍历也是bfs的最简单情况,这里我就将二叉树的层序遍历以及常考问题给大家分享一下。

在了解二叉树的遍历之前,需要具备数据结构与算法有队列、递归、栈、二叉树,这些内容咱们前面都有讲过,有这方面知识欠缺的同学可以往前翻一翻看一看!

层序遍历

层序遍历,听名字也知道是按层遍历。一个节点有左右节点,按层处理就是当前层兄弟节点的优先级要大于子节点处理的优先级,所以就是要将子节点放到后面处理,这就适合队列这个数据结构用来存储。

对于队列,先进先出。从root节点push到队列,那么队列中先出来的顺序是第二层的左右(假设都有),第二层每个节点执行的时候按照左右顺序添加到队列,第三层的节点就会有序的放到最后面……按照这样的规则就能得到一个层序遍历的顺序。

实现的代码也很容易理解:

public int[] levelOrder(TreeNode root) {int arr[]=new int[10000];int index=0;Queue<TreeNode>queue=new ArrayDeque<>();if(root!=null)queue.add(root);while (!queue.isEmpty()){TreeNode node=queue.poll();arr[index++]= node.val;if(node.left!=null)queue.add(node.left);if(node.right!=null)queue.add(node.right);}return Arrays.copyOf(arr,index);}

分层存储

但是在具体笔试他可能要求你分层存储,例如力扣的102二叉树的层序遍历,要求返回一个List<List<Integer>>类型。

这种相比上面一个多了一层逻辑就是每一层数据放到一块,这个也很容易,最好想到的就是两个队列(容器)一层一层遍历存储,然后交替,但是两个队列(容器)的写法常常会被面试官嫌弃,很多面试官让你想想怎么不用两个容器实现?

不用双队列去枚举结果也很容易,重要的就是先记录队列大小size(当前层节点数量),然后执行size次数的枚举即可,具体代码为:

public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>>list=new ArrayList<List<Integer>>();if(root==null)return list;Queue<TreeNode>q1=new ArrayDeque<TreeNode>();q1.add(root);while (!q1.isEmpty()) {int size=q1.size();List<Integer>value=new ArrayList<Integer>();for(int i=0;i<size;i++){TreeNode pNode=q1.poll();if(pNode.left!=null)q1.add(pNode.left);if(pNode.right!=null)q1.add(pNode.right);value.add(pNode.val);}list.add(value);}return list;
}

之字形打印

除了这个直接层序遍历,二叉树还有很高频的就是之字形遍历,例如剑指offer32和力扣103 二叉树的锯齿形层序遍历,它的题目要求为:

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

这道题虽然不是难题,但是有点绕,本来队列这玩意我们就要大脑想一下什么顺序,又出来一个之字形,属实增加的思维逻辑,有不少小伙伴反映当时面试官让手撕这道题,自己以前明明写过,但是太紧张自己给自己绕进去了!

其实这个问题也很容易转化,因为值只是存储,我们按照老样子去进行层序遍历,只不过在遍历时候通过当前层奇偶数来给它判断是从左往右存储到结果中还是从右往左放到结果中。当然,判断奇数偶数也很容易,可以用变量,也可以用结果List的size()都可。

个人实现的一个朴素代码为:

public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> value=new ArrayList<>();//存储到的最终结果if(root==null)return value;int index=0;//判断Queue<TreeNode>queue=new ArrayDeque<>();queue.add(root);while (!queue.isEmpty()){List<Integer>va=new ArrayList<>();//临时 用于存储到value中int len=queue.size();//当前层的数量for(int i=0;i<len;i++){TreeNode node=queue.poll();if(index%2==0)va.add(node.val);elseva.add(0,node.val);if(node.left!=null)queue.add(node.left);if(node.right!=null)queue.add(node.right);}value.add(va);index++;}return value;
}

上面实现代码也仅使用一个队列,不过这个问题可能有很多更巧妙的解法需要大家自己去挖掘。

结语

二叉树的层序遍历是二叉树内容中较为简单的内容,但是层序遍历尤其是之字形遍历(锯齿形遍历)出现的频率真的太高了,并且最好是掌握比较好的方法不要显得太臃肿。

不过在实际遇到问题时候,能AC是第一位,然后才是精简的逻辑和骚气的代码。

二叉树层序遍历变种问题不多,掌握上面三个问题基本就够了,而二叉树的前序、中序、后序遍历(递归非递归)考察非常多,后面会给大家加快梳理总结,敬请期待!

如果文章对你有帮助,欢迎关注我↓,回复【666】免费获得我自己的原创pdf! 咱们下次再见!

一次字节面试,被二叉树的层序遍历捏爆了相关推荐

  1. 二叉树的层序遍历(两种方法实现)

    两种方法实现二叉树的层序遍历 1.说明 二叉树的层序遍历是面试经常会被考察的知识点,甚至要求当场写出实现过程. 层序遍历所要解决的问题很好理解,就是按二叉树从上到下,从左到右依次打印每个节点中存储的数 ...

  2. Java实现自定义队列和树结构_实现二叉树的层序遍历,说说Java中的队列结构(实现一个Java的队列)...

    几次面试都被问到二叉树的层序遍历,需要用到队列这个数据结构,我一直想使用一个队列来实现,但是java里没有一种好的队列的数据结构,我又一次面试用ArrayList去当队列用,但是被面试官说到,是不对的 ...

  3. BFS和DFS两种方式实现二叉树的层序遍历

    二叉树文章系列: 二叉树的前序遍历 二叉树的中序遍历 二叉树的后序遍历 二叉树的层序遍历 二叉树的前序.中序.后序.层序遍历[解法完整版] 本文目录 前言 一.题目 二.思路分析 解法一:广度优先搜索 ...

  4. 二叉树的层序遍历 II

    二叉树的层序遍历 II 给定一个二叉树,返回其节点值自底向上的层序遍历. (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如: 给定二叉树 [3,9,20,null,null,15,7] ...

  5. [力扣] 二叉树的层序遍历

    [力扣] 二叉树的层序遍历 广度优先算法,遍历每一层的节点 例题: 102. 二叉树的层序遍历 # Definition for a binary tree node. # class TreeNod ...

  6. 算法--- 二叉树的层序遍历 II

    题目 二叉树的层序遍历 II 给定一个二叉树,返回其节点值自底向上的层序遍历. (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)例如: 给定二叉树 [3,9,20,null,null,15, ...

  7. 二叉树的层序遍历_NC15 求二叉树的层序遍历

    NC15 求二叉树的层序遍历 考过的企业 - 小米 题目描述 给定一个二叉树,返回该二叉树层序遍历的结果,(从左到右,一层一层地遍历) 例如:给定的二叉树是{3,9,20,#,#,15,7},该二叉树 ...

  8. Leetcode 102. Binary Tree Level Order Traversal(二叉树的层序遍历)

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

  9. LeetCode 102二叉树的层序遍历103二叉树锯齿形遍历104二叉树的最大深度

    微信搜一搜:bigsai 大家都在关注的刷题.学习数据结构和算法宝藏项目 关注回复进群即可加入力扣打卡群,欢迎划水.近期打卡: LeetCode 97交错字符串(动态规划) LeetCode 98验证 ...

最新文章

  1. FTP服务(vsftpd)配置
  2. java字符串类型常量拼接与变量拼接的区别
  3. Ubuntu16.04下创建工作空间并添加自己的功能包(python代码)
  4. maven的仓库、生命周期与插件
  5. 20200612:力扣192周周赛上
  6. PTA 基础编程题目集 (参考代码)
  7. 小新air14学计算机,小新Air14对比小新Pro13哪个更香,盘点办公学习的
  8. linux下oracle 9204 soft only,在CentOS4.3(x86_64)上安装Oracle9204 for linux(x86_64)
  9. java 生成word 分页_Java 插入分页符和分节符到Word文档
  10. Windows 10系统下Outlook日历怎么显示农历?
  11. matlab的setup阶跃曲线图,matlab 绘制系统的单位阶跃响应曲线 并编写程序求峰值时间 超调量 | 学步园...
  12. ipencil 无法与iPad配对
  13. 剪辑视频怎么加音效 视频音效常用都有哪些类型
  14. 【遗传算法GA】入门:基本介绍
  15. 802.1X与portal的无线认证
  16. java斜椭圆_JAVA 任意椭圆方向画法
  17. php实现等比例缩放图片
  18. 非专业人士对特斯拉人工智能日的专业解释 ——记@Cosmacelf在Reddit.com上对于AI Day的评价...
  19. python如何群控手机_python调用adb脚本来实现群控安卓手机初探
  20. 看图工具IrfanView

热门文章

  1. C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参推断
  2. Python 打包 exe 程序避坑指南:没有安装包也能运行小程序啦~开心
  3. 02-缓存一致性---实现big.LITTLE、GPU 计算和企业应用
  4. optee中关于异常向量表、中断等的深入思考
  5. python编写一个压测重启的测试程序
  6. optee系统服务/service的实现方式
  7. 关于CVE-2019-0708 - 数组越界
  8. html数字变换插件,轻量级jquery数字动画插件
  9. Windows进程与线程学习笔记(二)—— 线程结构体
  10. 设计模式C++实现(13)——中介者模式