跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

C++ 二叉树层序遍历:在每个树行中找最大值

使用 C++ 结合广度优先搜索(BFS)实现二叉树的层序遍历,并在每一层中找出最大值。核心思路是利用队列存储节点,通过记录当前层节点数量来区分层级,遍历过程中同步比较更新当前层最大值。需注意将最大值初始化为整型最小值以兼容负数节点,同时正确处理空树边界条件。该算法时间复杂度为 O(n),空间复杂度为 O(n)。

赛博朋克发布于 2026/3/16更新于 2026/4/2716 浏览
C++ 二叉树层序遍历:在每个树行中找最大值

一、题目描述

题目链接:力扣 515. 在每个树行中找最大值

题目描述:

给你一棵二叉树的根节点,请你找出每一层的最大值,并按层的顺序返回这些最大值组成的数组。

示例 1:
输入:root = [1,3,2,5,3,null,9]
输出:[1,3,9]

示例 2:
输入:root = [1,2,3]
输出:[1,3]

提示:
树中节点数目在范围 [0, 10⁴] 内
-2³¹ <= Node.val <= 2³¹ - 1

三、算法原理

本题的核心算法是'基于队列的 BFS 分层遍历 + 层内最大值统计',在基础层序遍历的框架上,仅增加'层内最大值初始化'和'逐节点值比较更新最大值'两步操作,逻辑清晰且易于理解。

  1. 初始化一个队列,把二叉树的根节点入队(若根节点为空,直接返回空结果)。
  2. 初始化一个结果数组,用于存储每一层的最大值。
  3. 当队列不为空时,执行以下操作:
    • 记录当前队列的大小(即当前层的节点数 n)。
    • 初始化当前层的最大值变量 max_val 为整型最小值(INT_MIN),确保能覆盖所有节点值的边界情况。
    • 循环 n 次,依次取出队列头部的节点:
      • 将当前节点值与 max_val 比较,更新 max_val 为两者中的较大值。
      • 若节点有左子节点,将左子节点入队;若有右子节点,将右子节点入队(为下一层遍历做准备)。
    • 将当前层的最大值 max_val 加入结果数组。
  4. 队列为空时,遍历完成,返回最终结果数组。

这个思路的本质是:用 BFS 完成分层遍历,在遍历每一层的过程中同步统计最大值,以最小的代码改动适配'层内找最大值'的需求。

模拟过程

我们用示例 1 完整模拟,帮你直观理解每一步的队列状态和最大值统计过程。

场景:示例 1 二叉树 [1,3,2,5,3,null,9]
初始状态:

  • 队列 q = [1]
  • 最终结果 ret = []
步骤队列状态当前层节点数 (n)当前层最大值 (max_val)节点值比较过程ret 变化
1[1]111 → max_val=1[1]
2[3,2]233→max_val=3 → 2→max_val 保持 3[1,3]
3[5,3,9]395→max_val=5 → 3→max_val 保持 5 → 9→max_val=9[1,3,9]
4[]0-队列空,结束遍历不变

细节注意

  1. 最大值初始化:必须用 INT_MIN(需包含 <climits> 头文件)初始化,不能用 0,否则无法正确处理全负数的二叉树(比如节点值为 [-5,-3,-8] 的情况)。
  • 子节点入队顺序:二叉树层序遍历需先入队左子节点、再入队右子节点,不影响最大值统计,但这是层序遍历的标准操作。
  • 边界条件:空树直接返回空数组,避免后续操作空指针;单节点树直接返回 [val],无需额外处理。
  • 常见错误与避坑

    1. 最大值初始化错误:二叉树节点的取值是有负数的,用 0 或 1 初始化最大值,会导致全负数节点的二叉树统计结果错误。
    2. 忘记处理空树:直接操作空根节点会触发空指针异常。
    3. 层内节点数获取时机错误:在循环过程中获取队列大小,而非循环前,导致统计的节点数混入下一层节点。
    4. 最大值更新逻辑错误:在节点入队后才更新最大值,导致当前节点值未被统计。

    四、代码实现

    #include <vector>
    #include <queue>
    #include <climits>
    
    using namespace std;
    
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        vector<int> largestValues(TreeNode* root) {
            // 存储每一层的最大值
            vector<int> ret;
            // 边界条件:空树直接返回空数组
            if (root == nullptr) return ret;
            
            // 标准队列存储二叉树节点,效率优于 vector 模拟
            queue<TreeNode*> q;
            q.push(root);
            
            // 队列非空则继续遍历
            while (!q.empty()) {
                // 记录当前层的节点数(循环前获取,避免混入下一层节点)
                int n = q.size();
                
                // 初始化当前层最大值为整型最小值,覆盖所有数值边界
                int max_val = INT_MIN;
                
                // 遍历当前层的所有节点
                for (int i = 0; i < n; i++) {
                    // 取出队头节点
                    TreeNode* tmp = q.front();
                    q.pop();
                    
                    // 核心:更新当前层的最大值
                    max_val = max(max_val, tmp->val);
                    
                    // 二叉树子节点入队:先左后右,保证层序遍历顺序
                    if (tmp->left != nullptr) q.push(tmp->left);
                    if (tmp->right != nullptr) q.push(tmp->right);
                }
                
                // 将当前层的最大值加入结果数组
                ret.push_back(max_val);
            }
            
            return ret;
        }
    };
    

    代码细节说明

    1. 队列的实现:使用 C++ 标准库的 queue<TreeNode*>(push 入队、front() 取队头、pop() 出队),相比 vector 模拟队列效率更高(queue 的 pop 操作时间复杂度为 O(1))。
    2. 核心逻辑:
      • 外层 while 循环:控制层的遍历,队列非空则继续;
      • 内层 for 循环:遍历当前层的所有节点,逐值比较更新最大值,并将子节点入队;
      • 最大值统计:用 max 函数比较当前节点值和已记录的最大值,确保每一层能找到最大的节点值。
    3. 数值边界处理:用 INT_MIN 初始化最大值,确保能正确处理节点值为负数的场景(比如节点值为 [-1,-2,-3] 时,仍能统计出 -1 作为第一层最大值)。

    复杂度分析

    • 时间复杂度:O(n)。n 是二叉树的节点数,每个节点入队、出队各一次(O(n));层内最大值比较操作总次数为 O(n)(每个节点仅参与一次比较),因此整体时间复杂度仍为 O(n)。
    • 空间复杂度:O(n)。最坏情况下(完美二叉树的最后一层),队列存储的节点数为 n/2,空间复杂度为 O(n);结果数组存储每一层的最大值,空间复杂度为 O(h)(h 为树的高度),整体空间复杂度为 O(n)。

    五、总结

    1. 核心逻辑:BFS 分层遍历 + 层内最大值统计是解决本题的核心,在遍历每一层节点的过程中同步更新最大值是最高效的方式。
    2. 细节要点:用 INT_MIN 初始化层内最大值以覆盖负数场景,层内节点数需在循环前获取,子节点需'先左后右'入队。
    3. 代码优化:标准库 queue 比 vector 模拟队列效率更高,层内比较操作不影响整体时间复杂度。

    目录

    1. 一、题目描述
    2. 三、算法原理
    3. 模拟过程
    4. 细节注意
    5. 常见错误与避坑
    6. 四、代码实现
    7. 代码细节说明
    8. 复杂度分析
    9. 五、总结
    • 💰 8折买阿里云服务器限时8折了解详情
    • 💰 8折买阿里云服务器限时8折购买
    • 🦞 5分钟部署阿里云小龙虾了解详情
    • 🤖 一键搭建Deepseek满血版了解详情
    • 一键打造专属AI 智能体了解详情
    极客日志微信公众号二维码

    微信扫一扫,关注极客日志

    微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

    更多推荐文章

    查看全部
    • Java 零基础入门教程:环境搭建与核心语法
    • MySQL 数据库安装与配置指南
    • Ollama 本地部署教程:Windows/Linux/Mac 安装与使用指南
    • 2026 年 AI 编程工具对比:GitHub Copilot、Cursor 与 Codeium 选型指南
    • SkyWalking 与 Spring Cloud Alibaba 全链路追踪实战
    • Python 自学入门指南:零基础到进阶学习路径规划
    • PageIndex 无分块文档索引技术详解
    • C++ 模板的幻觉:实例化、重定义与隐藏依赖
    • 5 款免费 AIGC 检测工具推荐与降重实践
    • Java 面试核心考点与实战解析
    • Flutter 底部导航与 TabBar 多页切换及鸿蒙适配
    • C++11 条件变量:notify_one 与 notify_all 的唤醒机制
    • 网络安全为什么缺人?缺什么样的人?
    • 春晚机器人刷屏,A 股板块为何高开低走?
    • Quilter:基于物理驱动的 AI 电路板设计工具
    • 基于火山引擎即梦 API 的数字人视频生成 Streamlit Demo
    • 数据结构:栈的原理与 C 语言实现
    • 宇树 G1 机器人二次开发:基于 FAST-LIO 的建图与 RViz 配置指南
    • 宇树机器人 G1 二次开发:FAST-LIO 建图与 RViz 配置教程
    • Web 应用中的 Cookie 与 Session:状态管理双刃剑

    相关免费在线工具

    • 加密/解密文本

      使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

    • Gemini 图片去水印

      基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

    • Base64 字符串编码/解码

      将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

    • Base64 文件转换器

      将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

    • Markdown转HTML

      将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

    • HTML转Markdown

      将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online