从零开始刷算法——二叉树篇:层序遍历 + 有序数组转二叉搜索树

在二叉树的算法体系中,"读取"(遍历)与"写入"(构建)是两个最核心的命题。

本文将通过两道经典题目——二叉树的层序遍历有序数组转搜索树,深入剖析两种截然不同的思维模式:基于队列的迭代(BFS)基于递归的分治(Divide & Conquer),并从内存与指针的角度分析其底层实现。


一、 读取的艺术:二叉树的层序遍历

二叉树的层序遍历(Level Order Traversal)本质上是图论中的广度优先搜索(BFS)。不同于前中后序遍历“一条道走到黑”的深度优先逻辑,层序遍历要求我们按照“剥洋葱”的方式,一层一层地访问节点。

1. 核心代码实现

C++代码实现:

class Solution { // 思路: 先加入root进q,然后每次处理完front()之后把它左右子树加入进去,最重要的其实还是要记录当前的size,来记录有几个数进入vals作为一组 public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> ans; if (root == nullptr) return ans; queue<TreeNode*> q; q.push(root); while (!q.empty()) { vector<int> vals; // 快照,核心逻辑:固定住当前层的 size for (int i = q.size(); i > 0; --i) { vals.push_back(q.front()->val); if (q.front()->left) q.push(q.front()->left); if (q.front()->right) q.push(q.front()->right); q.pop(); // 要不就提前用node记录下来front要不就最后pop } ans.push_back(vals); } return ans; } };

2. 深度解析:队列与快照机制

很多初学者容易写成普通的 BFS,却无法将结果按层分开。上述代码中最精髓的一行在于:

for (int i = q.size(); i > 0; --i)

这里隐藏了一个**“快照”**思想:

  1. 锁定状态:在进入for循环之前,q.size()代表了当前这一层所有的节点数量。我们必须在循环开始前就确定循环次数。

  2. 动态入队:在循环内部,我们不断地push下一层的节点(左右孩子)。

  3. 时空隔离:如果不固定i的次数,而是每次判断q.size(),那么新加入的下一层节点会和当前层混在一起,导致分层逻辑失效。

通过这个机制,队列q充当了一个缓冲区,完美地衔接了上一层的消耗和下一层的生产。

3. 时空复杂度分析

  • 时间复杂度:O(N)

    • 每个节点进队一次、出队一次,操作次数与节点总数 N 成正比。

  • 空间复杂度:O(W)

    • W 为二叉树的最大宽度。

    • 在最坏情况下(满二叉树的最底层),队列中需要同时存储大约 N/2 个节点,因此空间复杂度与宽度相关,数量级上视为 O(N)。


二、 构建的艺术:有序数组转二叉搜索树

如果说层序遍历是利用队列进行“横向扫描”,那么构建平衡二叉搜索树(BST)则是利用递归进行“纵向切分”。

题目要求构建高度平衡的 BST,且输入数组是有序的。这天然符合二分法分治思想

1. 核心代码实现

C++代码实现:

class Solution { // 思路: 题目要求平衡也就是左右高度差为1以内, 那肯定要涉及到中间点, 利用二分的思想构造子树, dfs递归构造, 因为是左小右大, 所以构造左边从mid左边选,右边从mid右边选 TreeNode* dfs(vector<int>& nums, int left, int right) { if (left > right) return nullptr; int mid = left + (right - left) / 2; TreeNode* root = new TreeNode(nums[mid]); root->left = dfs(nums, left, mid - 1); root->right = dfs(nums, mid + 1, right); return root; } public: TreeNode* sortedArrayToBST(vector<int>& nums) { return dfs(nums, 0, nums.size() - 1); } };

2. 深度解析:堆内存与指针构建

在这段简短的递归代码中,TreeNode* root = new TreeNode(nums[mid]);这行代码极其关键,它揭示了 C++ 中二叉树构建的内存模型:

  1. 堆区(Heap)分配

    • 使用了new关键字。这意味着节点对象是创建在堆内存中的。

    • 这一点至关重要。如果是栈上分配(例如TreeNode node;),函数dfs一结束,节点就会被销毁。而堆上分配的节点生命周期独立于函数调用,保证了整棵树在递归结束后依然存在。

  2. 栈区(Stack)链接

    • dfs函数的每一次调用都在系统栈中开辟了一个栈帧。

    • 变量root是一个指针,暂存在栈上。

    • root->left = dfs(...)这一步,实际上是利用栈上的递归回溯,将分散在堆内存中的各个节点,通过指针像“锁链”一样串联起来,形成了树的结构。

这种**“取中点 -> 建根 -> 递归构建左右”的顺序,本质上是二叉树的前序遍历**逻辑。

3. 时空复杂度分析

  • 时间复杂度:O(N)

    • 每个数组元素只会被访问一次用来创建一个节点,不存在重复计算。

  • 空间复杂度:O(log N)

    • 这里的空间消耗主要来自递归调用栈

    • 由于我们每次都取中间点(mid),保证了生成的树是高度平衡的。

    • 平衡二叉树的高度是log N,因此递归的最大深度也就是log N

    • 注:这里未计算存储结果所需的 O(N) 空间,仅计算算法辅助空间。


三、 总结

这两道题目展示了二叉树算法的两种极端:

  1. 层序遍历

    • 数据结构:队列 (Queue)

    • 特性:FIFO (先进先出)

    • 思维:迭代,水平扩展,通过 size控制层级。

  2. 平衡构建

    • 数据结构:系统栈 (System Stack / Recursion)

    • 特性:LIFO (后进先出)

    • 思维:递归,深度优先,通过二分保证平衡。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1155493.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么说RAG是AI 2.0时代的“杀手级”应用?

你好&#xff0c;我是常扬&#xff0c;欢迎你加入到《RAG 快速开发实战》课程的学习中。在正式开始之前&#xff0c;我想先介绍一下自己&#xff0c;我本科在同济大学学习软件工程&#xff0c;后来又在复旦大学攻读人工智能方向的硕士和博士&#xff0c;期间发表过多篇 SCI 核心…

零基础也能学懂提示词?OpenCSG公益课给出清晰学习路径:从“会问”到“会驱动”

提示词工程的进阶路径不是背技巧&#xff0c;而是从简单到复杂的“表达升级”。本文给出零基础可执行的学习路线与写法框架&#xff0c;让你用自然语言更精确地驱动AI完成复杂任务。 一、先建立一个判断&#xff1a;你写的不是“问题”&#xff0c;而是“任务指令” 很多提示…

通义深度搜索-生成对话

产品链接 面向深度的查询问答和调研分析需求场景,多步骤推理规划研究路径,生成有洞察、可溯源、图文并茂的长文报告-大模型服务平台百炼(Model Studio)-阿里云帮助中心 本产品&#xff08;通义深度搜索&#xff09;对外服务接口目录。所有接口使用 DashScope HTTP 协议对外提…

机器学习:基于python二手房数据分析系统 可视化 Scrapy 爬虫 链家二手房数据 Django框架 基于用户的协同过滤推荐 二手房推荐系统 (源码)

博主介绍&#xff1a;✌全网粉丝10W&#xff0c;前互联网大厂软件研发、集结硕博英豪成立软件开发工作室&#xff0c;专注于计算机相关专业项目实战6年之久&#xff0c;累计开发项目作品上万套。凭借丰富的经验与专业实力&#xff0c;已帮助成千上万的学生顺利毕业&#xff0c;…

机器学习:python招聘数据分析可视化系统 机器学习 招聘推荐 薪资预测 爬虫 决策树回归模型 XGBoost回归模型 Flask框架 前程无忧

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ > &#x1f345;想要获取完整文章或者源码&#xff0c;或者代做&#xff0c;拉到文章底部即可与…

书籍-塔西佗《编年史》

塔西佗《编年史》详细介绍 书籍基本信息 书名&#xff1a;编年史&#xff08;Annales / Ab Excessu Divi Augusti&#xff09; 作者&#xff1a;塔西佗&#xff08;Publius Cornelius Tacitus&#xff0c;约56-120年&#xff09; 成书时间&#xff1a;约公元110-120年 卷数&…

如何翻译图片?图片上的外语一键翻译成中文,教程来了~

工程图纸是扫描图可以翻译吗&#xff1f;手机拍的图纸照片可以翻译吗&#xff1f;图片形式的图纸可以翻译吗&#xff1f;针对以上三类工程图纸翻译常见问题&#xff0c;进行统一答复&#xff1a;PlanForm-AI工程图纸翻译都可以翻译&#xff0c;教程如下&#xff1a;1.如果你遇到…

物联网毕设 基于单片机的红外热视仪(源码+硬件+论文)

文章目录 0 前言1 主要功能2 硬件设计3 核心软件设计4 实现效果5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己…

机器学习:python租房数据分析可视化系统 K-means聚类算法 线性回归预测算法 机器学习 链家租房网 Django框架 scrapy 爬虫(建议收藏)

博主介绍&#xff1a;✌全网粉丝10W&#xff0c;前互联网大厂软件研发、集结硕博英豪成立软件开发工作室&#xff0c;专注于计算机相关专业项目实战6年之久&#xff0c;累计开发项目作品上万套。凭借丰富的经验与专业实力&#xff0c;已帮助成千上万的学生顺利毕业&#xff0c;…

OpenCSG课程精华:为什么结构化提示词更有效?Markdown / XML / JSON 的正确打开方式

构化提示词的关键不是“好看”&#xff0c;而是边界清晰、可被系统消费。本文解释 Markdown、XML、JSON 三种结构化方式的适用场景&#xff0c;并给出更稳的输出控制方法。 一、结构化的意义&#xff1a;先解决“边界不清”&#xff0c;再谈“表达优雅” 大模型最怕的是混淆&…

jmeter基础知识-安装配置环境变量

1.安装JDK 2.配置java环境变量 搜索栏输入编辑环境变量 用户变量&#xff1a;只对当前用户生效 系统变量&#xff1a;对所有用户生效 点击新建在变量名中输入&#xff1a;JAVA_HOME 变量值中输入jdk的安装路径 例如&#xff1a;C:\ProgramFiles\Java\jdk1.8.0_161 再次点击…

RH134 第八章 管理存储堆栈

一 创建和拓展逻辑卷1.1 逻辑卷&#xff08;LVM&#xff09;概念LVM 有助于更加轻松地管理磁盘空间。可以将卷组 Volume Group 中的可用空间分配给逻辑卷 (Logical Volume)&#xff0c;并且可以调整文件系统的大小✔ 如果磁盘出现错误&#xff0c;可将替换磁盘注册为物理卷 (Ph…

什么是PKI

文章目录 为什么需要PKIPKI应用场景有哪些PKI是如何工作的 公钥基础设施PKI&#xff08;Public Key Infrastructure&#xff09;&#xff0c;是一种遵循既定标准的证书管理平台&#xff0c;它利用公钥技术能够为所有网络应用提供安全服务。PKI技术是信息安全技术的核心&#xf…

在Spring Boot项目中,Shiro和Spring Security该如何选择?

安全管理是Java应用开发中无法避免的问题&#xff0c;随着Spring Boot和微服务的流行&#xff0c;Spring Security受到越来越多Java开发者的重视&#xff0c;究其原因,还是沾了微服务的光。作为Spring家族中的一员,其在和Spring家族中的其他产品如SpringBoot、Spring Cloud等进…

2026软件测试金3银4常见的软件测试面试题

现阶段很多测试同行抱怨工作难找&#xff0c;网上的面试题又真不真实先不说&#xff0c;乱七八糟的&#xff0c;下面是我耗费了三个月时间的、结合真实的实际面试情况所写下的真实软件测试面试题以及&#xff0c;如何回答&#xff0c;总共十个章节以及写成一个文档全文8w多个字…

从GPT到智能体:OpenCSG带你看清提示词工程的“执行力升级”——拆分步骤、工具调用与安全边界

复杂任务失败的根源&#xff0c;常常不是模型不行&#xff0c;而是“一步到位”不成立。本文给出可落地的拆分方法、多轮调用策略&#xff0c;并补齐智能体场景下必须重视的安全边界。 一、复杂任务的第一原则&#xff1a;不要指望“一次调用做完一切” 当任务包含“理解→规…

计算机毕业设计springboot二手房租售管理系统设计与实现 基于Spring Boot框架的二手房交易与租赁管理系统开发与应用 Spring Boot驱动的二手房买卖及租赁信息管理平台设计与实现

计算机毕业设计springboot二手房租售管理系统设计与实现z86u2 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。随着房地产市场的不断发展&#xff0c;二手房交易和租赁的需求日益…

计算机毕业设计springboot校园服务平台 基于SpringBoot的校园综合服务平台设计与实现 SpringBoot框架下的校园服务管理系统开发

计算机毕业设计springboot校园服务平台alsns9 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。随着信息技术的飞速发展&#xff0c;校园管理和服务的数字化转型已成为必然趋势。传…

强烈安利9个AI论文网站,本科生毕业论文轻松搞定!

强烈安利9个AI论文网站&#xff0c;本科生毕业论文轻松搞定&#xff01; 2.「云笔AI」—— 解决 “杂事”&#xff0c;节省时间&#xff08;推荐指数&#xff1a;★★★★☆&#xff09; “云笔AI”是一款专为学术写作设计的智能工具&#xff0c;它的核心优势在于能够帮助用户高…

只需根据接口文档,就能轻松开发 get 和 post 请求的脚本

前言 一般的接口文档描述的内容&#xff1a; ​开发get请求的脚本&#xff0c;接口文档的描述如下&#xff1a; 在loadrunner里面创建一个空脚本&#xff1a; ​在action空白处&#xff0c;点击insert—>step 输入web_custom_request&#xff0c;双击选择该函数&#xff0c…