Java中关于二叉树层序遍历深入了解

前言

大家好,我是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);
      else
        va.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是第一位,然后才是精简的逻辑和骚气的代码。

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

到此这篇关于Java中关于二叉树层序遍历深入了解的文章就介绍到这了,更多相关Java 二叉树层序遍历内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java实现的二叉树常用操作【前序建树,前中后递归非递归遍历及层序遍历】

    本文实例讲述了Java实现的二叉树常用操作.分享给大家供大家参考,具体如下: import java.util.ArrayDeque; import java.util.Queue; import java.util.Stack; //二叉树的建树,前中后 递归非递归遍历 层序遍历 //Node节点 class Node { int element; Node left; Node right; public Node() { } public Node(int element) { this.

  • Java中关于二叉树层序遍历深入了解

    前言 大家好,我是bigsai,在数据结构与算法中,二叉树无论是考研.笔试都是非常高频的考点内容,在二叉树中,二叉树的遍历又是非常重要的知识点,今天给大家讲讲二叉树的层序遍历. 这部分很多人可能会但是需要注重一下细节. 前面介绍了二叉排序树的构造和基本方法的实现,遍历也是比较重要的一环,并且二叉树的层序遍历也是bfs的最简单情况,这里我就将二叉树的层序遍历以及常考问题给大家分享一下. 在了解二叉树的遍历之前,需要具备数据结构与算法有队列.递归.栈.二叉树,这些内容咱们前面都有讲过,有这方面知识欠

  • C语言二叉树层序遍历

    实现下面图中的二叉树层序遍历 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <unistd.h> typedef struct node { char data; struct node *lchild; struct node *rchild; }NODE, *PNODE; typedef struct qnode { PNODE pnode; struct qno

  • C++实现LeetCode(107.二叉树层序遍历之二)

    [LeetCode] 107. Binary Tree Level Order Traversal II 二叉树层序遍历之二 Given the root of a binary tree, return the bottom-up level order traversal of its nodes' values. (i.e., from left to right, level by level from leaf to root). Example 1: Input: root = [3

  • C++实现LeetCode(102.二叉树层序遍历)

    [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, level by level). For example: Given binary tree {3,9,20,#,#,15,7},     3 / \ 9  20 /  \ 15 

  • Java中关于二叉树的概念以及搜索二叉树详解

    目录 一.二叉树的概念 为什么要使用二叉树? 树是什么? 树的相关术语! 根节点 路径 父节点 子节点 叶节点 子树 访问 层(深度) 关键字 满二叉树 完全二叉树 二叉树的五大性质 二.搜索二叉树 插入 删除 hello, everyone. Long time no see. 本期文章,我们主要讲解一下二叉树的相关概念,顺便也把搜索二叉树(也叫二叉排序树)讲一下.我们直接进入正题吧!GitHub源码链接 一.二叉树的概念 为什么要使用二叉树? 为什么要用到树呢?因为它通常结合了另外两种数据结

  • 详解Java中两种分页遍历的使用姿势

    在日常开发中,分页遍历迭代的场景可以说非常普遍了,比如扫表,每次捞100条数据,然后遍历这100条数据,依次执行某个业务逻辑:这100条执行完毕之后,再加载下一百条数据,直到扫描完毕 那么要实现上面这种分页迭代遍历的场景,我们可以怎么做呢 本文将介绍两种使用姿势 常规的使用方法 借助Iterator的使用姿势 1. 数据查询模拟 首先mock一个分页获取数据的逻辑,直接随机生成数据,并且控制最多返回三页 public static int cnt = 0; private static List

  • Java中List集合的遍历实例详解

     一.对List的遍历有三种方式   List<String> list = new ArrayList<String>(); list.add("testone"); list.add("testtwo"); ... 第一种: for(Iterator<String> it = list.iterator(); it.hasNext(); ) { .... } 这种方式在循环执行过程中会进行数据锁定,    性能稍差,    同

  • java中File类应用遍历文件夹下所有文件

    本文要求遍历指定文件夹下的所有文件,包括子文件夹下的文件,供大家参考,具体内容如下 代码: package 遍历文件夹所有文件; import java.io.File; public class Test { public static void main(String[] args){ File file=new File("D:\\tcb\\周总结"); filesDirs(file); } //使用递归遍历文件夹及子文件夹中文件 public static void files

  • java中List集合及其遍历详解

    1. 首先List<E>集合继承与Collection<E>,是一个接口. ①  Collection (集合框架是JDK1.2版本出现的) ②   list:是有序的,元素可以重复,以为该集合体系有索引.    经常用到的是实现该接口的ArrayList和LinkedList类 ③   Arraylist:  底层的数据结构使用的是数组结构, 特点: 查询速度很快,但是增删稍慢.线程不同步 LinkedList: 底层使用的是链表数据结构. 特点: 增删速度很快,查询稍慢. Ve

  • JS中的二叉树遍历详解

    二叉树是由根节点,左子树,右子树组成,左子树和友子树分别是一个二叉树. 这篇文章主要在JS中实现二叉树的遍历. 一个二叉树的例子 var tree = { value: 1, left: { value: 2, left: { value: 4 } }, right: { value: 3, left: { value: 5, left: { value: 7 }, right: { value: 8 } }, right: { value: 6 } } } 广度优先遍历 广度优先遍历是从二叉树

随机推荐