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

前言

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

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


一、题目阅读

【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.rhkb.cn/news/375519.html

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

相关文章

服务攻防——中间件Jboss

文章目录 一、Jboss简介二、Jboss渗透2.1 JBoss 5.x/6.x 反序列化漏洞&#xff08;CVE-2017-12149&#xff09;2.2 JBoss JMXInvokerServlet 反序列化漏洞&#xff08;CVE-2015-7501&#xff09;2.3 JBossMQ JMS 反序列化漏洞&#xff08;CVE-2017-7504&#xff09;2.4 Adminis…

【逆向基础】十、工具分享之DIE(Detect It Easy)

一、简介 DIE&#xff08;Detect It Easy&#xff09;是一款可以轻松检测PE文件的程序&#xff1b;其主要作用是查壳&#xff0c;并将pe文件的内容解析出来&#xff0c;包括PE文件中包含的导入函数、导出函数的名称及地址&#xff0c;入口函数地址等&#xff0c;是技术人员分析…

如何在小红书上面有效地种草?

文末领取小红书电商开店运营教程&#xff01; 小红书是一个以内容分享为主的社交平台&#xff0c;大家喜欢在这里分享自己的生活体验和心得&#xff0c;其中就包括各种产品的使用感受。 那么我们要想在小红书上有效地种草&#xff0c;首先就需要了解并掌握小红书的种草文化。 …

Elasticsearch详细介绍

B站对应视频&#xff1a; Elasticsearch01-01.为什么学习elasticsearch_哔哩哔哩_bilibili 大多数日常项目&#xff0c;搜索肯定是访问频率最高的页面之一。目前搜索功能是基于数据库的模糊搜索来实现的&#xff0c;存在很多问题。 首先&#xff0c;查询效率较低。 由于数据…

libcoap3对接华为云平台

文章目录 前言一、平台注册二、引入源码库1.libcoap仓库编译2.分析网络报文3.案例代码4.编译&运行 总结 前言 通过libcoap3开源代码库对接华为云平台&#xff0c;本文章将讨论加密与不加密的方式对接华为云平台。 一、平台注册 首先&#xff0c;你需要在华为云平台上创建…

QT之嵌入外部第三方软件到本窗体中

一、前言 使用QT开发&#xff0c;有时需要调用一些外部程序&#xff0c;但是单独打开一个外部窗口有的场合很不合适&#xff0c;最好是嵌入到开发的QT程序界面中。还有就是自己开发的n个程序&#xff0c;一个主程序托n个子程序&#xff0c;为了方便管理将各个程序独立&#xf…

安全防御---防火墙实验1

安全防御—防火墙实验1 一、实验拓扑与要求 要求&#xff1a; 1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内&#xff08;9&#xff1a;00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 …

华为手机联系人不见了怎么恢复?3个解决方案

华为手机联系人列表就像是我们精心编织的社交网络之网。然而&#xff0c;有时&#xff0c;这张网可能会因为各种原因而意外破损&#xff0c;联系人信息消失得无影无踪&#xff0c;让我们陷入“人脉孤岛”的困境。华为手机联系人不见了怎么恢复&#xff1f;别担心&#xff0c;我…

计算机网络——数据链路层(以太网)

目录 局域网的数据链路层 局域网可按照网络拓扑分类 局域网与共享信道 以太网的两个主要标准 适配器与mac地址 适配器的组成与运作 MAC地址 MAC地址的详细介绍 局域网的mac地址格式 mac地址的发送顺序 单播、多播&#xff0c;广播mac地址 mac帧 如何取用…

【面试八股总结】线程基本概念,线程、进程和协程区别,线程实现

一、什么是线程&#xff1f; 线程是“轻量级进程”&#xff0c;是进程中的⼀个实体&#xff0c;是程序执⾏的最小单元&#xff0c;也是被系统独立调度和分配的基本单位。 线程是进程当中的⼀条执行流程&#xff0c;同⼀个进程内多个线程之间可以共享代码段、数据段、打开的文件…

解决:Flink向kafka写数据使用Producer精准一次(EXACTLY_ONCE)异常

在使用flink向kafka写入数据报错&#xff1a;Caused by: org.apache.kafka.common.KafkaException: Unexpected error in InitProducerIdResponse; The transaction timeout is larger than the maximum value allowed by the broker (as configured by transaction.max.timeou…

【C++】哈希表的模拟实现及 unordered_set 和 unorderded_map 的封装

目录 前言一、哈希表的模拟实现1.1 哈希表的改造1.1.1 模板参数列表的改造1.1.2 增加迭代器操作 1.2 哈希表的模拟实现1.2.1 哈希表中仿函数的实现1.2.2 哈希表中节点类的实现1.2.3 哈希表中迭代器类的实现1.2.4 哈希表中构造函数、析构函数和 Clear() 函数的实现1.2.5 哈希表中…

[笔试训练](三十六)106:提取不重复的整数107:哈夫曼编码108:abb

目录 106:提取不重复的整数 107:哈夫曼编码 108:abb 106:提取不重复的整数 题目链接:提取不重复的整数_牛客题霸_牛客网 (nowcoder.com) 题目: ​ 题解: #include <iostream> #include <string> using namespace std; int n0; int cnt[10]; int ret0; int mai…

【pytorch18】Logistic Regression

回忆线性回归 for continuous:y xwbfor probability output:yσ(xwb) σ:sigmoid or logistic 线性回归是简单的线性模型&#xff0c;输入是x&#xff0c;网络参数是w和b&#xff0c;输出是连续的y的值 如何把它转化为分类问题?加了sigmoid函数&#xff0c;输出的值不再是…

Python精神病算法和自我认知异类数学模型

&#x1f3af;要点 &#x1f3af;空间不确定性和动态相互作用自我认知异类模型 | &#x1f3af;精神病神经元算法推理 | &#x1f3af;集体信念催化个人行动力数学模型 | &#x1f3af;物种基因进化关系网络算法 | &#x1f3af;电路噪声低功耗容错解码算法 &#x1f4dc;和-…

动手学深度学习(Pytorch版)代码实践 -循环神经网络-55循环神经网络的从零开始实现和简洁实现

55循环神经网络的实现 1.从零开始实现 import math import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2l import matplotlib.pyplot as plt import liliPytorch as lp# 读取H.G.Wells的时光机器数据集 batch_size, num_ste…

C语言中的数组:掌握数据的有序集合【一维数组,二维数组,字符串数组,直方图打印,计算全排列,字符数组常用函数】

目录 C语言中的数组&#xff1a;掌握数据的有序集合【一维数组&#xff0c;二维数组&#xff0c;字符串数组】一维数组一维数组的创建数组的七种初始化完全初始化&#xff1a;部分初始化&#xff1a;字符数组的初始化&#xff1a;自动初始化为0&#xff1a;使用memset函数初始化…

『大模型笔记』GraphRAG:用于复杂数据发现的新工具现已在GitHub上发布

GraphRAG:用于复杂数据发现的新工具现已在GitHub上发布 文章目录 一. GraphRAG:用于复杂数据发现的新工具现已在GitHub上发布1. 评估和结果2. 研究见解和未来方向二. 参考文献一. GraphRAG:用于复杂数据发现的新工具现已在GitHub上发布 下载 GraphRAG今年早些时候,我们介绍…

博客建站3 - 购买域名

1. 本网站的系统架构2. 选择域名 2.1. 确定域名关键词2.2. 保持简洁易记2.3. 检查域名可用性 3. 域名注册商 3.1. 海外的提供商 3.1.1. GoDaddy3.1.2. Namecheap3.1.3. Google Domains 3.2. 国内的提供商 3.2.1. 阿里云&#xff08;Alibaba Cloud&#xff09;3.2.2. 腾讯云&…

0502STM32EXTI中断项目代码实现

STM32EXTI中断函数代码实现 对射式红外传感器&旋转编码器计次配置外部中断的步骤&#xff1a;AFIO相关函数&GPIO的一个函数EXTI相关函数代码NVIC中断函数启动文件里的中断函数名字中断编程的建议&#xff1a; 对射式红外传感器&旋转编码器计次 一般一个模块要写的…