数据结构二叉树——层序遍历&& 扩展二叉树的左视图

二叉树的层序遍历

层序遍历的特点是:从上到下、从左到右依次访问每一层的所有节点,就像 "按楼层逐层扫描"。例如,对于这样一棵二叉树:

层序遍历的结果是 [[3], [9, 20], [15, 7]](每一层的节点值组成一个子列表)。

实现的关键是利用队列的 "先进先出(FIFO)" 特性:

  • 先访问的节点,其左右孩子也会按顺序先被访问,恰好符合层序遍历的 "从左到右" 规则。
  • 每次处理完一层的所有节点后,队列中剩余的节点恰好是下一层的所有节点。
    地址https://leetcode.cn/problems/binary-tree-level-order-traversal/description/
    核心是用 队列(FIFO 先进先出特性)实现二叉树的层序遍历
    本质是 "按楼层逐层扫描节点"
    把每一层的节点值整理成列表

1.初始化准备

  • 创建一个外层列表 list,用于存储最终的层序遍历结果(每个元素是一层的节点值列表)。
  • 特殊情况处理:如果根节点 root 为 null(空树),直接返回空列表。
  • 创建一个队列 queue(用 LinkedList 实现),用于存储待访问的节点,初始时将根节点入队。

2.逐层遍历节点

使用 while 循环持续处理队列中的节点,直到队列为空(所有节点都访问完毕)

3. 处理当前层的所有节点

  • 创建当前层的列表:List list2 用于存储当前层所有节点的值。
  • 记录当前层的节点数量:int size = queue.size(),这个 size
    就是当前层的节点总数(必须先记录,因为后续队列会加入下一层的节点,大小会变化)。
  • 循环处理当前层的每个节点:用 for 或 while 循环执行 size 次,每次取出队列的头节点
java 复制代码
while (size != 0) {
    TreeNode cur = queue.poll(); // 取出队首节点(当前层的一个节点)
    list2.add(cur.val); // 将当前节点的值加入当前层列表
    ...
    size--;
}

4. 把下一层的节点入队

对于当前节点 cur,如果它有左孩子或右孩子,就将它们依次加入队列(保证下一层的节点按 "从左到右" 的顺序等待访问)

java 复制代码
if (cur.left != null) {
    queue.offer(cur.left); // 左孩子入队
}
if (cur.right != null) {
    queue.offer(cur.right); // 右孩子入队
}

5. 收集当前层结果

当前层的所有节点处理完毕后,list2 中已经存储了当前层的所有节点值,将其加入外层列表 list

java 复制代码
list.add(list2);

6. 循环结束,返回结果

当队列空了(queue.isEmpty() 为 true),说明所有层都已处理完毕,返回外层列表 list 即可。

java 复制代码
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        // 创建双层的顺序表,存储最终结果的列表
        List<List<Integer>> list = new ArrayList<>();
        if (root == null) {
            return list;
        }

        // 创建队列,注意需要存储TreeNode类型
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root); 

        // 队列不为空时循环(处理每一层)
        while (!queue.isEmpty()) {
            // 存储当前层的节点值
            List<Integer> list2 = new ArrayList<>();
            // 当前层的节点数量(必须先记录,因为队列大小会动态变化)
            int size = queue.size();

            // 循环处理当前层的所有节点
            while (size != 0) {
            // 取出队首节点
                TreeNode cur = queue.poll(); 
                // 把当前节点的值加入当前层列表
                list2.add(cur.val); 
                // 左孩子非空则入队
                if (cur.left != null) {
                    queue.offer(cur.left);
                }
                // 右孩子非空则入队
                if (cur.right != null) {
                    queue.offer(cur.right);
                }
// 处理完一个节点,当前层剩余数量减1
                size--; 
            }
            list.add(list2);
        }
        return list;
    }
}

扩展题

二叉树的左右视图

左右视图的核心是获取每一层的 "第一个节点"(左视图)或 "最后一个节点"(右视图),可通过层序遍历实现:

按层遍历二叉树(同层序遍历逻辑)。

对每一层的节点,仅记录 "第一个节点"(左视图)或 "最后一个节点"(右视图)。

相信大家比上面那个自己动手敲了出来,这个很快的就想到怎么做出来

无非就是把每一个第一个或者最后一个重新存储起来

java 复制代码
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> leftView(TreeNode root) {
        // 存储左视图结果(每一层的第一个节点)
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        // 队列不为空时,逐层处理(复用层序遍历的外层循环)
        while (!queue.isEmpty()) {
            // 当前层的节点数量(必须先记录,队列大小会动态变化)
            int size = queue.size();

            // 循环处理当前层的所有节点(复用层序遍历的内层循环)
            for (int i = 0; i < size; i++) {
                TreeNode cur = queue.poll();
                // 核心逻辑:只记录当前层的第一个节点(i=0时)这就是左视图
                if (i == 0) {
                    result.add(cur.val);
                }
                // 左孩子先入队(保证下一层节点从左到右顺序,复用层序遍历的入队逻辑)
                if (cur.left != null) {
                    queue.offer(cur.left);
                }
                // 右孩子后入队
                if (cur.right != null) {
                    queue.offer(cur.right);
                }
            }
        }

        return result;
    }
}
相关推荐
筱砚.3 小时前
【数据结构——最小生成树与Kruskal】
数据结构·算法
Orange_sparkle3 小时前
若依使用基本步骤
java·vue
kevinfkq3 小时前
Java-idea编辑器中Jar方式打包启动
java·intellij-idea·jar
噢,我明白了4 小时前
前端js 常见算法面试题目详解
前端·javascript·算法
€8114 小时前
Java入门级教程23——配置Nginx服务器、轻量级HTTP服务开发、前后端分离实现完整应用系统
java·开发语言·仓颉·生成验证码
星秀日4 小时前
框架--SpringMVC
java·开发语言·servlet
小蒜学长4 小时前
springboot餐厅信息管理系统设计(代码+数据库+LW)
java·数据库·spring boot·后端
蒙奇D索大4 小时前
【数据结构】考研数据结构核心考点:平衡二叉树(AVL树)详解——平衡因子与4大旋转操作入门指南
数据结构·笔记·学习·考研·改行学it
怎么没有名字注册了啊5 小时前
查找成绩(数组实现)
c++·算法