每日打卡:二叉树的层序遍历

109 阅读1分钟

这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:

输入:root = [3,9,20,null,null,15,7]

输出:[[3],[9,20],[15,7]

原题链接

今天我们就来聊一聊我们的树,树可能是我们2所学的数据结构当中最难理解的变种最多的了,之前也一直抗拒做树相关的题,但是你也不能不做啊,你得硬着头皮上啊,

回顾深度和广度遍历

首先需要先介绍我们树相关的两种遍历,我们的深度遍历和广度遍历,这两中遍历的方式我猜大家应该都知道,我就简单的写一下实现

深度遍历,实现深度最简单的办法就是递归了,

void dfs(TreeNode root) {
    if (root == null) {
        return;
    }
    dfs(root.left);
    dfs(root.right);
}

广度遍历就比深度遍历看起来要复杂很多,我们使用了队列来维护

void bfs(TreeNode root) {
    Queue<TreeNode> queue = new ArrayDeque<>();
    queue.add(root);
    while (!queue.isEmpty()) {
        
        TreeNode node = queue.poll(); 
        if (node.left != null) {
            queue.add(node.left);
        }
        if (node.right != null) {
            queue.add(node.right);
        }
    }
}

其实,我们这两种排序都使用了数据结构,我们深度排序因为使用的是递归,他用隐匿的方式调用了栈的结构

对于深度遍历就不说过多的解读了

EE46A2C003E43E97AA4AC576E13D6126.jpg 我们详细了解一下我们广度遍历在队列的存储过程

  • 节点1入队,节点1出队,访问节点1
  • 节点1的孩子节点2,3入队,节点2出队,访问节点2
  • 节点2的孩子节点 4,5入队
  • 节点3出队,访问就节点3
  • 节点3的孩子节点6入队
  • 节点4出队,访问节点4,没有孩子节点
  • 节点5出队,访问节点5
  • 节点5的孩子节点7 入队
  • 节点6出队,访问节点6
  • 节点6的孩子节点8,9入队
  • 节点7,8,9出队

解题

我们深度和广度遍历了解之后,我们一下子就能发现我们这道题使用广度遍历,做起来可能更容易一些。 但我们仔细读题,我们需要将一层的数据装入一个集合,那我们靠什么去分割呢?

我们仔细看一下上面广度遍历在队列中的入队和出队的顺序,

首先,只有父节点出队,子节点才会入队

所以我们可以推导出,我们上层节点全部出队,我们的下层节点全部入队,那我们就可以用此时的队列长度来分割

 public List<List<Integer>> levelOrder(TreeNode root) {
         List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(root==null){
            return result;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);
        while (!queue.isEmpty()) {
            //创建集合来实现我们队列
            List<Integer> list = new ArrayList<Integer>();
            //获取队列长度
            int size = queue.size();
            //i没有实际作用
            for (int i = 0; i <size; i++){
                //从队列中取出一个节点,判断他是否有子节点,有则入队
                TreeNode node = queue.poll();
                list.add(node.val);
                if(node.left !=null){
                    queue.add(node.left);
                }
                if(node.right != null){
                    queue.add(node.right);
                }
            }
            result.add(list);
        }
        return result;
    
    }