当前位置: 首页 > news >正文

代码随想录 二叉树 test 2

二叉树的非递归遍历

先序

方法一:

先保存根节点,用来之后找到右子树(利用栈来回溯到根,进而找到右子树)

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> res;    //存遍历序列stack<TreeNode*> stk;TreeNode* p = root;while(p || !stk.empty()){if(p != nullptr){   res.push_back(p->val);  //访问根节点stk.push(p);p = p->left;    //移动到左子树}else{  //如果左子树为空,就需要访问上一个结点的右子树p = stk.top();stk.pop();p = p->right;}}return res;}
};

方法二:

不用回溯,利用栈的先进后出性质,先将右子树入栈,再将左子树入栈,实现根左右。

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {if(!root) return {};vector<int> res;    //存遍历序列stack<TreeNode*> stk;stk.push(root);while(!stk.empty()){TreeNode* p = stk.top();stk.pop();res.push_back(p->val);    //根if(p->right) stk.push(p->right);    //将非空的右孩子压栈if(p->left) stk.push(p->left);    //将非空的左孩子压栈}return res;}
};

方法三:统一迭代法

每次以根节点为处理对象,如果当前遍历的结点非空,则按照右左根顺序,将三个结点都压入栈中,在压入根节点之后继续压入空指针,因此处理顺序与出栈顺序对应。如果为空,则当前该结点需要输出。

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> res;    //存遍历序列if(!root)   return res;stack<TreeNode*> stk;stk.push(root);while(!stk.empty()){TreeNode* p = stk.top();if(p != nullptr){stk.pop();if(p->right) stk.push(p->right);   //右if(p->left) stk.push(p->left);  //左stk.push(p);    //中stk.push(nullptr);  //标记在空结点之下即为要处理的结点}else{stk.pop();  //弹出空结点p = stk.top();  //访问要处理的结点stk.pop();  //弹出已处理好的结点res.push_back(p->val);}}return res;}
};

中序

方法一


与先序方法一类似,将访问结点操作放在遍历到当前最左结点之后。

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> res;    //存遍历序列stack<TreeNode*> stk;TreeNode* p = root;while(p || !stk.empty()){if(p != nullptr){   stk.push(p);p = p->left;    //移动到左子树}else{  //如果左子树为空,就需要访问上一个结点的右子树p = stk.top();stk.pop();res.push_back(p->val);  //访问左p = p->right;}}return res;}
};

方法二:统一迭代法

只需将先序中的统一迭代法,按照右根左入栈即可。

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> res;    //存遍历序列if(!root)   return res;stack<TreeNode*> stk;stk.push(root);while(!stk.empty()){TreeNode* p = stk.top();if(p != nullptr){stk.pop();if(p->right) stk.push(p->right);   //右stk.push(p);    //中stk.push(nullptr);  //标记在空结点之下即为要处理的结点if(p->left) stk.push(p->left);  //左}else{stk.pop();  //弹出空结点p = stk.top();  //访问要处理的结点stk.pop();  //弹出已处理好的结点res.push_back(p->val);}}return res;}
};

后序

方法一

改写先序方法一,由于遍历顺序要求是左右根,因此回溯的情况既可能是遍历完左子树也可能是遍历完右子树。如果是遍历完左子树且有右子树且右子树未被遍历过,则需要继续遍历右子树,如果是遍历完右子树,则此时栈顶元素即为当前最右,需要进行处理,处理完最右结点需要回溯到根,因此需要将当前指针置为空,在下一次循环就可以取出栈顶根。由上可知需要标记结点是否被遍历过,因此需要一个指针r记录上一个遍历过的结点。

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> res;    //存遍历序列stack<TreeNode*> stk;TreeNode* p = root;TreeNode* r = nullptr;while(p || !stk.empty()){if(p != nullptr){   stk.push(p);p = p->left;    //移动到左子树}else{  //如果左子树为空,就需要检查右子树状态p = stk.top();if(p->right && r != p->right){  //如果有右子树且未被遍历过p = p->right;}else{  //否则应该处理栈顶元素p = stk.top();stk.pop();res.push_back(p->val);  //处理栈顶r = p;  //标记此结点已被处理p = nullptr;}}}return res;}
};

方法二:改写先序方法二+反转

先序方法二颠倒左右子树入栈顺序实现根右左,再进行反转,变成左右根。

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {if(!root) return {};vector<int> res;    //存遍历序列stack<TreeNode*> stk;stk.push(root);while(!stk.empty()){TreeNode* p = stk.top();stk.pop();res.push_back(p->val);    //根if(p->left) stk.push(p->left);    //将非空的左孩子压栈if(p->right) stk.push(p->right);    //将非空的右孩子压栈}reverse(res.begin(), res.end());    //反转数组return res;}
};

方法三:统一迭代法

按照根右左顺序入栈

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> res;    //存遍历序列if(!root)   return res;stack<TreeNode*> stk;stk.push(root);while(!stk.empty()){TreeNode* p = stk.top();if(p != nullptr){stk.pop();stk.push(p);    //中stk.push(nullptr);  //标记在空结点之下即为要处理的结点if(p->right) stk.push(p->right);   //右if(p->left) stk.push(p->left);  //左}else{stk.pop();  //弹出空结点p = stk.top();  //访问要处理的结点stk.pop();  //弹出已处理好的结点res.push_back(p->val);}}return res;}
};

相关文章:

代码随想录 二叉树 test 2

二叉树的非递归遍历 先序 方法一: 先保存根节点&#xff0c;用来之后找到右子树(利用栈来回溯到根&#xff0c;进而找到右子树) class Solution { public:vector<int> preorderTraversal(TreeNode* root) {vector<int> res; //存遍历序列stack<TreeNode*…...

浏览器默认语言与页面访问统计问题二三则

文章目录 前言网站默认语言问题网站访问统计问题Error: Empty components are self-closingError: A space is required before closing bracket 总结 前言 看标题大概能猜到这是一篇杂合体的总结&#xff0c;是这两天处理网站遇到的小问题&#xff0c;怕过段时间再忘了所以总…...

用Python绘制一只懒羊羊

目录 一、准备工作 二、Turtle库简介 三、绘制懒羊羊的步骤 1. 导入Turtle库并设置画布 2. 绘制头部 3. 绘制眼睛 4. 绘制嘴巴 5. 绘制身体 6. 绘制四肢 7. 完成绘制 五、运行代码与结果展示 六、总结 在这个趣味盎然的技术实践中,我们将使用Python和Turtle图形…...

虹科分享 | 汽车NVH小课堂之听音辨故障

随着车主开始关注汽车抖动异响问题&#xff0c;如何根据故障现象快速诊断异响来源&#xff0c;成了汽修人的必修课。 一个比较常用的方法就是靠“听”——“听音辨故障”。那今天&#xff0c;虹科Pico也整理了几个不同类型的异响声音&#xff0c;一起来听听看你能答对几个吧 汽…...

论文速读|SigLIP:Sigmoid Loss for Language Image Pre-Training.ICCV23

论文地址&#xff1a;https://arxiv.org/abs/2303.15343v4 代码地址&#xff1a;https://github.com/google-research/big_vision bib引用&#xff1a; misc{zhai2023sigmoidlosslanguageimage,title{Sigmoid Loss for Language Image Pre-Training}, author{Xiaohua Zhai and…...

深度学习笔记——循环神经网络之LSTM

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍面试过程中可能遇到的循环神经网络LSTM知识点。 文章目录 文本特征提取的方法1. 基础方法1.1 词袋模型&#xff08;Bag of Words, BOW&#xff09;工作…...

算法整理:2-opt求解旅行商(Python代码)

文章目录 算法思想算法步骤代码1纯函数代码2纯函数数据可视化 算法思想 通过交换边进行寻优。 算法步骤 把初始解作为当前解 通过交换边生成新解 如果新解优于历史最优解&#xff0c;则更新当前解为新解 重复2&#xff0c;3&#xff0c;直到当前解交换了所有的边均不能改…...

状态模式

在软件开发过程中&#xff0c;我们经常会遇到这样的情况&#xff1a;一个对象的行为会随着其内部状态的改变而发生变化。例如&#xff0c;一个手机在不同状态下&#xff08;开机、关机、静音等&#xff09;对相同的操作&#xff08;如来电&#xff09;会有不同的反应。传统的解…...

RoHS 简介

RoHS&#xff08;Restriction of Hazardous Substances Directive&#xff0c;限制有害物质指令&#xff09;是欧盟制定的一项环保法规&#xff0c;旨在限制电气和电子设备中某些有害物质的使用&#xff0c;以减少这些产品对环境和人体健康的危害。 RoHS限制的有害物质及其限量…...

【Vim Masterclass 笔记26】S11L46:Vim 插件的安装、使用与日常管理

文章目录 Section 11&#xff1a;Vim PluginsS11L46 Managing Vim Plugins1 第三方插件管理工具2 安装插件使用的搜索引擎3 Vim 插件的安装方法4 存放 Vim 插件包的路径格式5 示例一&#xff1a;插件 NERDTree 的安装6 示例二&#xff1a;插件 ctrlp.vim 的安装7 示例三&#x…...

深度学习原理与Pytorch实战

深度学习原理与Pytorch实战 第2版 强化学习人工智能神经网络书籍 python动手学深度学习框架书 TransformerBERT图神经网络&#xff1a; 技术讲解 编辑推荐 1.基于PyTorch新版本&#xff0c;涵盖深度学习基础知识和前沿技术&#xff0c;由浅入深&#xff0c;通俗易懂&#xf…...

ELK环境搭建

文章目录 1.ElasticSearch安装1.安装的版本选择1.SpringBoot版本&#xff1a;2.4.2 找到依赖的spring-data-elasticsearch的版本2.spring-data-elasticsearch版本&#xff1a;4.1.3 找到依赖的elasticsearch版本3.elasticsearch版本&#xff1a;7.9.3 2.安装1.官方文档2.下载压…...

基于Springboot + vue实现的民俗网

“前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能学习网站” &#x1f496;学习知识需费心&#xff0c; &#x1f4d5;整理归纳更费神。 &#x1f389;源码免费人人喜…...

第24篇 基于ARM A9处理器用汇编语言实现中断<六>

Q&#xff1a;怎样设计ARM处理器汇编语言程序使用定时器中断实现实时时钟&#xff1f; A&#xff1a;此前我们曾使用轮询定时器I/O的方式实现实时时钟&#xff0c;而在本实验中将采用定时器中断的方式。新增第三个中断源A9 Private Timer&#xff0c;对该定时器进行配置&#…...

【数据结构】_不带头非循环单向链表

目录 1. 链表的概念及结构 2. 链表的分类 3. 单链表的实现 3.1 SList.h头文件 3.2 SList.c源文件 3.3 Test_SList.c测试文件 关于线性表&#xff0c;已介绍顺序表&#xff0c;详见下文&#xff1a; 【数据结构】_顺序表-CSDN博客 本文介绍链表&#xff1b; 基于顺序表…...

golang 使用双向链表作为container/heap的载体

MyHeap&#xff1a;container/heap的数据载体&#xff0c;需要实现以下方法&#xff1a; Len&#xff1a;堆中数据个数 Less&#xff1a;第i个元素 是否必 第j个元素 值小 Swap&#xff1a;交换第i个元素和 第j个元素 Push&#xff1a;向堆中追加元素 Pop&#xff1a;从堆…...

C#集合操作优化:高效实现批量添加与删除

在C#中&#xff0c;对集合进行批量操作&#xff08;如批量添加或删除元素&#xff09;通常涉及使用集合类型提供的方法和特性&#xff0c;以及可能的循环或LINQ查询来高效地处理大量数据。以下是一些常见的方法和技巧&#xff1a; 批量添加元素 使用集合的AddRange方法&#x…...

142.WEB渗透测试-信息收集-小程序、app(13)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;141.WEB渗透测试-信息收集-小程序、app&#xff08;12&#xff09; 软件用法&#xff0c…...

24.日常算法

1. 数组中两元素的最大乘积 题目来源 给你一个整数数组 nums&#xff0c;请你选择数组的两个不同下标 i 和 j&#xff0c;使 (nums[i]-1)*(nums[j]-1) 取得最大值。请你计算并返回该式的最大值。 示例 1&#xff1a; 输入&#xff1a;nums [3,4,5,2] 输出&#xff1a;12 解释…...

分布式理解

分布式 如何理解分布式 狭义的分布是指&#xff0c;指多台PC在地理位置上分布在不同的地方。 分布式系统 分布式系**统&#xff1a;**多个能独立运行的计算机&#xff08;称为结点&#xff09;组成。各个结点利用计算机网络进行信息传递&#xff0c;从而实现共同的“目标或者任…...

wordpress调用指定ID页面的链接

在WordPress中&#xff0c;如果你想调用一个指定ID的页面链接&#xff0c;可以使用以下几种方法&#xff1a; 方法一&#xff1a;使用页面ID 你可以直接使用页面的ID来生成链接。例如&#xff0c;如果你想链接到ID为123的页面&#xff0c;可以使用以下代码&#xff1a; <…...

单值二叉树(C语言详解版)

一、摘要 今天要讲的是leetcode单值二叉树&#xff0c;这里用到的C语言&#xff0c;主要提供的是思路&#xff0c;大家看了我的思路之后可以点击链接自己试一下。 二、题目简介 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。 只有给定的树是单…...

python学opencv|读取图像(四十二)使用cv2.add()函数实现多图像叠加

【1】引言 前序学习过程中&#xff0c;掌握了灰度图像和彩色图像的掩模操作&#xff1a; python学opencv|读取图像&#xff08;九&#xff09;用numpy创建黑白相间灰度图_numpy生成全黑图片-CSDN博客 python学opencv|读取图像&#xff08;四十&#xff09;掩模&#xff1a;三…...

速通Docker === Docker Compose

目录 Docker Compose 简介 Docker Compose 常用命令 使用 Docker Compose 启动 WordPress 普通启动方式&#xff08;使用 Docker 命令&#xff09; 使用 Docker Compose 启动 Docker Compose 的特性 Docker Compose 简介 Docker Compose 是一个用于定义和运行多容器 Dock…...

LMI Gocator GO_SDK VS2019引用配置

LMI SDK在VS2019中的引用是真的坑爹,总结一下经验,希望后来的人能少走弯路.大致内容如下: &#xff08;1&#xff09; 环境变量 &#xff08;2&#xff09;C/C 附加包含目录 E:\GWQ\Gocator\GO_SDK\Gocator\GoSdk E:\GWQ\Gocator\GO_SDK\Platform\kApi &#xff08;3&#…...

技术之翼,创作之心

引言&#xff1a;初入编程的迷茫与追求 当我第一次接触到编程时&#xff0c;心中充满了既期待又迷茫的情感。那时&#xff0c;我还是一名刚刚踏入大学的学生&#xff0c;面对一门陌生而复杂的学科——计算机科学&#xff0c;我的内心充满了好奇与困惑。课堂上&#xff0c;老师…...

WebSocket异步导出

WebSocket异步导出 1、安装sockjs-client和stompjs2、连接后台3、vite.config.ts 配置反向代理4、导出并实时通信5、 封装WebSocket 文件注册登录(城通网盘) 1、安装sockjs-client和stompjs import SockJS from sockjs-client/dist/sockjs.min.js import Stomp from stompjs2、…...

OS2.【Linux】基本命令入门(1)

目录 1.操作系统是什么? 2.好操作系统的衡量标准 3.操作系统的核心工作 4.在计算机上所有行为都会被转换为硬件行为 5.文件 6.简单介绍一些基本命令 1.clear 2.pwd 3.ls 1.ls -l 2.隐藏文件的创建 3.ls -al 4.ls -ld 5.ls -F(注意是大写) 4.cd 1.cd .. "…...

【二叉树】4. 判断一颗二叉树是否是平衡二叉树。5. 对称二叉树。6. 二叉树的构建及遍历 7. 二叉树的分层遍历 。

判断一颗二叉树是否是平衡二叉树。OJ链接 可以在求树高度的过程中判断树是否平衡 对称二叉树。OJ链接 二叉树的构建及遍历。OJ链接 注意&#xff1a;public static int i最好把static去掉 否则当有多个测试用例时 i无法重新为0二叉树的分层遍历 。OJ链接 但此题要求返回List…...

OS Copilot功能测评:智能助手的炫彩魔法

简介&#xff1a; OS Copilot 是一款融合了人工智能技术的智能助手&#xff0c;专为Linux系统设计&#xff0c;旨在提升系统管理和运维效率。本文详细介绍了在阿里云ECS实例上安装和体验OS Copilot的过程&#xff0c;重点评测了其三个核心参数&#xff1a;-t&#xff08;模式…...