代码随想录 二叉树 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
二叉树的非递归遍历 先序 方法一: 先保存根节点,用来之后找到右子树(利用栈来回溯到根,进而找到右子树) 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 总结 前言 看标题大概能猜到这是一篇杂合体的总结,是这两天处理网站遇到的小问题,怕过段时间再忘了所以总…...
用Python绘制一只懒羊羊
目录 一、准备工作 二、Turtle库简介 三、绘制懒羊羊的步骤 1. 导入Turtle库并设置画布 2. 绘制头部 3. 绘制眼睛 4. 绘制嘴巴 5. 绘制身体 6. 绘制四肢 7. 完成绘制 五、运行代码与结果展示 六、总结 在这个趣味盎然的技术实践中,我们将使用Python和Turtle图形…...
虹科分享 | 汽车NVH小课堂之听音辨故障
随着车主开始关注汽车抖动异响问题,如何根据故障现象快速诊断异响来源,成了汽修人的必修课。 一个比较常用的方法就是靠“听”——“听音辨故障”。那今天,虹科Pico也整理了几个不同类型的异响声音,一起来听听看你能答对几个吧 汽…...
论文速读|SigLIP:Sigmoid Loss for Language Image Pre-Training.ICCV23
论文地址:https://arxiv.org/abs/2303.15343v4 代码地址:https://github.com/google-research/big_vision bib引用: misc{zhai2023sigmoidlosslanguageimage,title{Sigmoid Loss for Language Image Pre-Training}, author{Xiaohua Zhai and…...
深度学习笔记——循环神经网络之LSTM
大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细介绍面试过程中可能遇到的循环神经网络LSTM知识点。 文章目录 文本特征提取的方法1. 基础方法1.1 词袋模型(Bag of Words, BOW)工作…...
算法整理:2-opt求解旅行商(Python代码)
文章目录 算法思想算法步骤代码1纯函数代码2纯函数数据可视化 算法思想 通过交换边进行寻优。 算法步骤 把初始解作为当前解 通过交换边生成新解 如果新解优于历史最优解,则更新当前解为新解 重复2,3,直到当前解交换了所有的边均不能改…...
状态模式
在软件开发过程中,我们经常会遇到这样的情况:一个对象的行为会随着其内部状态的改变而发生变化。例如,一个手机在不同状态下(开机、关机、静音等)对相同的操作(如来电)会有不同的反应。传统的解…...
RoHS 简介
RoHS(Restriction of Hazardous Substances Directive,限制有害物质指令)是欧盟制定的一项环保法规,旨在限制电气和电子设备中某些有害物质的使用,以减少这些产品对环境和人体健康的危害。 RoHS限制的有害物质及其限量…...
【Vim Masterclass 笔记26】S11L46:Vim 插件的安装、使用与日常管理
文章目录 Section 11:Vim PluginsS11L46 Managing Vim Plugins1 第三方插件管理工具2 安装插件使用的搜索引擎3 Vim 插件的安装方法4 存放 Vim 插件包的路径格式5 示例一:插件 NERDTree 的安装6 示例二:插件 ctrlp.vim 的安装7 示例三&#x…...
深度学习原理与Pytorch实战
深度学习原理与Pytorch实战 第2版 强化学习人工智能神经网络书籍 python动手学深度学习框架书 TransformerBERT图神经网络: 技术讲解 编辑推荐 1.基于PyTorch新版本,涵盖深度学习基础知识和前沿技术,由浅入深,通俗易懂…...
ELK环境搭建
文章目录 1.ElasticSearch安装1.安装的版本选择1.SpringBoot版本:2.4.2 找到依赖的spring-data-elasticsearch的版本2.spring-data-elasticsearch版本:4.1.3 找到依赖的elasticsearch版本3.elasticsearch版本:7.9.3 2.安装1.官方文档2.下载压…...
基于Springboot + vue实现的民俗网
“前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能学习网站” 💖学习知识需费心, 📕整理归纳更费神。 🎉源码免费人人喜…...
第24篇 基于ARM A9处理器用汇编语言实现中断<六>
Q:怎样设计ARM处理器汇编语言程序使用定时器中断实现实时时钟? A:此前我们曾使用轮询定时器I/O的方式实现实时时钟,而在本实验中将采用定时器中断的方式。新增第三个中断源A9 Private Timer,对该定时器进行配置&#…...
【数据结构】_不带头非循环单向链表
目录 1. 链表的概念及结构 2. 链表的分类 3. 单链表的实现 3.1 SList.h头文件 3.2 SList.c源文件 3.3 Test_SList.c测试文件 关于线性表,已介绍顺序表,详见下文: 【数据结构】_顺序表-CSDN博客 本文介绍链表; 基于顺序表…...
golang 使用双向链表作为container/heap的载体
MyHeap:container/heap的数据载体,需要实现以下方法: Len:堆中数据个数 Less:第i个元素 是否必 第j个元素 值小 Swap:交换第i个元素和 第j个元素 Push:向堆中追加元素 Pop:从堆…...
C#集合操作优化:高效实现批量添加与删除
在C#中,对集合进行批量操作(如批量添加或删除元素)通常涉及使用集合类型提供的方法和特性,以及可能的循环或LINQ查询来高效地处理大量数据。以下是一些常见的方法和技巧: 批量添加元素 使用集合的AddRange方法&#x…...
142.WEB渗透测试-信息收集-小程序、app(13)
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:141.WEB渗透测试-信息收集-小程序、app(12) 软件用法,…...
24.日常算法
1. 数组中两元素的最大乘积 题目来源 给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。请你计算并返回该式的最大值。 示例 1: 输入:nums [3,4,5,2] 输出:12 解释…...
分布式理解
分布式 如何理解分布式 狭义的分布是指,指多台PC在地理位置上分布在不同的地方。 分布式系统 分布式系**统:**多个能独立运行的计算机(称为结点)组成。各个结点利用计算机网络进行信息传递,从而实现共同的“目标或者任…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
