算法力扣刷题记录 三十七【二叉树层序遍历】

前言

二叉树递归遍历和二叉树迭代遍历 实现的前中后序遍历都归类深度搜索

广度搜索如何实现?一层结束,再继续下一层搜索:层序遍历。


一、题目阅读

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

示例 1:
在这里插入图片描述

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

示例 2:

输入:root = [1]
输出:[[1]]

示例 3:

输入:root = []
输出:[]

提示:

树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000

二、尝试实现

思路

(1)深度搜索中迭代循环使用的数据结构是栈,也是递归实现的原理。那么广度搜索(层序遍历)可不可以有数据结构用呢?如果还用栈,放入左右孩子时,无论是先入谁,出栈都不是按层出。所以得换。
(2)用队列怎么样?先把根节点入队,再入左孩子,再入右孩子。出队时,排序是层序结构。选定队列结构
(3)如果只是输出顺序,用队列把左右孩子不为空时,放入队列,按顺序出队就好了;但是结果需要按层划分数组,这就麻烦点。
(4)如果按sum求和,到第二层时sum=3,……到第n层是sum = 2^n -1。如果少了一边孩子,无法计数,依靠数量关系不好处理
(5)受迭代统一写法启发,如果每一层结束后面紧跟着null标记,从队列中取出空节点,说明一层结束,这就有了标志,nice。

代码实现

迭代实现:

/*** 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<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;	//先把返回值搞好queue<TreeNode*> que;	//定义一个队列if(root == nullptr) return result;que.push(root);	//如果第一层不是空,放入队列que.push(nullptr);//紧接着放入null,表示第一层结束。vector<int> levelrecord;//每一层的数组while(!que.empty()){TreeNode* cur = que.front();//获取队列出口元素if(cur!=nullptr){	//如果不为空,把左右孩子放入队列,前提左右孩子不为空时。if(cur->left) que.push(cur->left);if(cur->right)  que.push(cur->right);que.pop();	//取出出口元素levelrecord.push_back(cur->val);//放入当前层的数组中}else{	//如果取到空,说明这一层数组填好了。该往result里面放。que.pop();	//弹出空指针if(!levelrecord.empty()) result.push_back(levelrecord);	//如果该层不为空放入resultif(que.back() != nullptr){	//当队列还有元素,把层标记放进去;如果没有元素,说明已经到最后一层了,不用放入。que.push(nullptr);}levelrecord.clear();	//新的一层开始,清空上一层的存放}}return result;}
};

三、参考思路

二叉树层序遍历参考链接

学习内容

(1)借助队列,保存每一层的数据。如何实现?
(2)当一层的数组要放入result中时,用size来记录当前队列里元素的数量,这个数量是下一层的个数。只pop出size个元素放到当前层数组中。
(3)这样就不会出现两层元素混在一起。不知道这一层应该有几个元素。

对比思路总结:都是用队列来记录每一层的元素,但是如何知道每层元素个数方式不太一样:

  • 参考给出用size记录;
  • 个人想借助null标记表示一层结束。

代码实现

/*** 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<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;queue<TreeNode*> que;if(root != nullptr) que.push(root);while(!que.empty()){int size = que.size();	//在还没遍历这一层时,先把这一层的元素个数记录下来。vector<int> levelrecord;while(size--){	//边遍历边放入下一层元素。TreeNode* top = que.front();que.pop();if(top->left) que.push(top->left);if(top->right) que.push(top->right);levelrecord.push_back(top->val);}result.push_back(levelrecord);}return result;}
};

总结

本文记录二叉树层序遍历(广度搜索)的实现。

  • 借助队列结构;
  • 在遍历之前,记录每一层的个数。避免两层元素混在一起。

补充

迭代法:直接用循环实现同一段代码的重复操作;
递归:通过自己调用自己,也实现某段代码的重复操作。
那么用递归来实现层序遍历呢?

递归思路

  • 每一层遍历都是重复的操作,所以把层遍历的while(size- -)改成函数,实现递归。获得一层的数组。
  • 在主函数的while中调用递归函数。

代码实现

/*** 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:void traversal(queue<TreeNode*>& q,vector<int>& levelrecord,int size){if(size == 0){	//确定回归的终止条件return;}//还不到回归的条件TreeNode* cur = q.front();q.pop();if(cur->left) q.push(cur->left);if(cur->right) q.push(cur->right);levelrecord.push_back(cur->val);size--;traversal(q,levelrecord,size);	//重复执行}vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;queue<TreeNode*> que;if(root != nullptr) que.push(root);while(!que.empty()){int size =que.size();vector<int> vec;traversal(que,vec,size);result.push_back(vec);}return result;}
};

对比参考代码:
(1)在主函数中只调用一次递归函数,函数返回后,就可以return result。
(2)在递归函数order中:

  • 多层同时开展,先处理自己;再order左孩子;再order右孩子。
  • 如果没有新开一层,result已经放了该层数组
  • 如果新开一层,result需要push_back新数组。

流程如下
在这里插入图片描述

/*** 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:void order(TreeNode* cur,vector<vector<int>>& result,int depth){if(cur == nullptr) return;  //终止条件if(result.size() == depth ) result.push_back(vector<int> ());//新开一层,放入新数组,空的。result[depth].push_back(cur->val);order(cur->left,result,depth+1);//左孩子在下一层,所以result的下标应该+1order(cur->right,result,depth+1);//先左孩子再右孩子,可以使那一层从左到右。}vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;int depth = 0;//因为result数组下标从0开始order(root,result,depth);return result;}
};

(欢迎指正,转载标明出处)

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

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

相关文章

如何在iPhone上恢复图片?5 个有效解决方案

对于许多iPhone用户来说&#xff0c;照片是存储在他们设备上的最重要的数据&#xff0c;因此丢失这些照片可能是一场灾难。 但是&#xff0c;即使您不小心删除了iPhone上的部分或全部图片&#xff0c;也可以将其取回。 我们将讨论如何在有或没有备份的情况下在iPhone上恢复已…

面试篇-Mysql-2+事务隔离级别的实现

文章目录 前言一、Mysql 的事务你了解吗二、你了解Mysql 的事务隔离级别吗&#xff1a;2.1 你知道Mysql 的脏读&#xff0c;不可重复读&#xff0c;幻读的问题吗&#xff1a;2.1.1 脏读&#xff1a;2.1.2 不可重复读&#xff1a;2.1.3 幻读&#xff1a; 2.2 对于并发场景下的脏…

Python使用策略模式和openpyxl库创建Excel文件并追加内容

from openpyxl import load_workbook# 数据数组 data [[1, 2, 3],[4, 5, 6],[7, 8, 9] ]# 打开现有的 Excel 文件 excel_file sheetApend_example.xlsx wb load_workbook(excel_file)# 选择要追加数据的工作表 sheet_name test_Sheet2 # 指定要追加数据的工作表名称 sheet…

AI Agent满级进化!骑马种田、办公修图,样样精通,昆仑万维等发布通用Agent新框架

【导读】智能体又双叒叕进化了&#xff01;这次&#xff0c;什么游戏都能玩&#xff0c;什么软件都能操控了。 近日&#xff0c;昆仑万维携手北京智源人工智能研究院、新加坡南洋理工大学、北京大学等顶尖名校机构&#xff0c;联合提出了迄今为止第一个既能玩多种商业游戏又能…

Excel的Index+MATCH组合使用方法

INDEX函数 INDEX函数作用&#xff1a;用于从指定的单元格区域中返回特定行和列的值。 参数形式为&#xff1a;INDEX(array, row_num, [column_num]) array&#xff1a;必需。单元格区域或数组常量。 row_num&#xff1a;必需。要返回的值所在的行号。 [column_num]&#x…

【算法】【二分法】二分法详解

先给y总打一个广告。&#xff08;我这种废物收不到钱&#xff09; 本科时候就在打蓝桥杯玩玩算法&#xff0c;当时听朋友的一个刷题且涵盖教程的网站&#xff0c;ACWING。 www.acwing.com 里面好处是大部分基础算法都有&#xff0c;Y总的视频&#xff01; y总我的神&#xff01…

LLMs 入门实战系列

【LLMs 入门实战系列】 第一层 LLMs to Natural Language Processing (NLP) 第一重 ChatGLM-6B 【ChatGLM-6B入门-一】清华大学开源中文版ChatGLM-6B模型学习与实战 介绍&#xff1a;ChatGLM-6B 环境配置 和 部署 【ChatGLM-6B入门-二】清华大学开源中文版ChatGLM-6B模型微调…

Rust入门实战 编写Minecraft启动器#5启动游戏

首发于Enaium的个人博客 好了&#xff0c;我们已经完成了所有的准备工作&#xff0c;现在我们可以开始编写启动游戏的代码了。 首先我们需要添加几个依赖。 model { path "../model" } parse { path "../parse" } download { path "../downlo…

ensp防火墙综合实验作业+实验报告

实验目的要求及拓扑图&#xff1a; 我的拓扑&#xff1a; 更改防火墙和交换机&#xff1a; [USG6000V1-GigabitEthernet0/0/0]ip address 192.168.110.5 24 [USG6000V1-GigabitEthernet0/0/0]service-manage all permit [Huawei]vlan batch 10 20 [Huawei]int g0/0/2 [Huawei-…

git常用命令及git分支

git常用命令及git分支 git常用命令设置用户签名初始化本地库查看本地库状态将文件添加到暂存区提交到本地库查看历史记录版本穿梭 git分支什么是分支分支的好处分支的操作查看分支创建分支切换分支合并分支合并冲突 git常用命令 设置用户签名 //设置用户签名 git config --gl…

Datawhale 2024 年 AI 夏令营第二期——基于术语词典干预的机器翻译挑战赛

#AI夏令营 #Datawhale #夏令营 1.赛事简介 目前神经机器翻译技术已经取得了很大的突破&#xff0c;但在特定领域或行业中&#xff0c;由于机器翻译难以保证术语的一致性&#xff0c;导致翻译效果还不够理想。对于术语名词、人名地名等机器翻译不准确的结果&#xff0c;可以通…

emqx 负载均衡配置 HAProxy 健康检查 轮询 haship

HAProxy配置文件 配置文件&#xff1a; /etc/haproxy/haproxy.cfg 负载均衡参数&#xff1a; 轮询方式轮询注解roundrobin基于权重进行轮叫调度的算法&#xff0c;在服务器的性能分布比较均匀时&#xff0c;这是一种最公平合理&#xff0c;常用的算法。此算法使用较为频…

【银河麒麟高级服务器操作系统】数据中心系统异常卡死分析处理建议

了解银河麒麟操作系统更多全新产品&#xff0c;请点击访问&#xff1a;https://product.kylinos.cn 1.服务器环境以及配置 【机型】浪潮NF5280M5 处理器&#xff1a; Intel 内存&#xff1a; 1T 【内核版本】 4.19.90-24.4.v2101.ky10.x86_64 【OS镜像版本】 银河麒麟…

PDF 中图表的解析探究

PDF 中图表的解析探究 0. 引言1. 开源方案探究 0. 引言 一直以来&#xff0c;对文档中的图片和表格处理都非常有挑战性。这篇文章记录一下最近工作上在这块的探究。图表分为图片和表格&#xff0c;这篇文章主要记录了对表格的探究。还有&#xff0c;我个人主要做日本项目&…

MFC Ribbon菜单 - 中英文实时切换方法

简介 最近在搞一个老外的项目&#xff0c;本来谈的好好的&#xff0c;纯英文界面。项目接近尾声了&#xff0c;又提出了中英文实时切换的新需求&#xff0c;没办法就只能想办法&#xff0c;毕竟客户最大嘛。 实现方法 还好本来的ribbon英文菜单不复杂&#xff0c;就用纯C编码…

Python轻松添加行编号到Word文档及删除行编号

Word文档中的行号&#xff08;行编号&#xff09;功能是对于精细化的文档编辑以及解析非常有用的功能。添加行号能够极大地提升文档的可读性和定位效率&#xff0c;尤其是在需要引用特定行内容时&#xff0c;为读者提供了清晰的指引&#xff0c;避免了不必要的混淆和误解。然而…

Java BigInteger 类

目录 BigInteger 1. 如何获取一个BigInteger类型的对象&#xff1f; &#xff08;1&#xff09;构造方法 &#xff08;2&#xff09;静态方法 2. 常用方法 BigInteger 可以用来表示很大很大的数&#xff0c;有多大都可以。通过创建对象调用相应的方法。详见&#xff1a;…

45、tomcat+课后实验

tomcat 1、tomcat tomcat和php一样&#xff0c;都是用来处理动态页面的。 tomcat也可以作为web应用服务器&#xff0c;开源的。 php .php tomcat .jsp nginx .html tomcat 是用Java代码写的程序&#xff0c;运行的是Java的web应用程序。 tomcat的特点和功能&#xff1a…

前端调试技巧(npm Link,vscode调试,浏览器调试等)

Npm Link 功能&#xff1a; 在本地开发npm模块的时候&#xff0c;我们可以使用npm link命令&#xff0c;将npm 模块链接到对应的运行项目中去&#xff0c;方便地对模块进行调试和测试 断点调试 vscode调试 Debug Vue2 Project 目标&#xff1a;在VSCode中调试项目代码…

DockerFile文件解析

DockerFile 要研究自己如何做一个镜像&#xff0c;而且微服务项目打包上云部署&#xff0c;Docker就是最方便的。 微服务打包成镜像&#xff0c;任何装了Docker的地方&#xff0c;都可以下载使用&#xff0c;极其的方便。 流程&#xff1a;开发应用>DockerFile>打包为…