二叉树篇--代码随想录算法训练营第十二天| 二叉树理论基础,二又树的递归遍历,二叉树的迭代遍历,二叉树的统一迭代法,二叉树的层序遍历

二叉树理论基础

 递归和迭代遍历相似处:入栈出栈均来自中节点,左右节点用来向下传递

二又树的递归遍历

视频讲解: 每次写递归都要靠直觉? 这次带你学透二叉树的递归遍历!

前序遍历

代码

class Solution {
public:void traversal(TreeNode* cur, vector<int>& vec) {if (cur == NULL) return;vec.push_back(cur->val);    // 中traversal(cur->left, vec);  // 左traversal(cur->right, vec); // 右}vector<int> preorderTraversal(TreeNode* root) {vector<int> result;traversal(root, result);return result;}
};

后序遍历

代码

void traversal(TreeNode* cur, vector<int>& vec) {if (cur == NULL) return;traversal(cur->left, vec);  // 左traversal(cur->right, vec); // 右vec.push_back(cur->val);    // 中
}

中序遍历

代码 

void traversal(TreeNode* cur, vector<int>& vec) {if (cur == NULL) return;traversal(cur->left, vec);  // 左vec.push_back(cur->val);    // 中traversal(cur->right, vec); // 右
}

二叉树的迭代遍历

使用栈数据结构 

视频讲解:

  • 写出二叉树的非递归遍历很难么?(前序和后序)(opens new window)
  • 写出二叉树的非递归遍历很难么?(中序))

前序遍历

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;st.push(root);while(!st.empty()){TreeNode* node = st.top();st.pop();if(node != nullptr) {result.push_back(node->val);st.push(node->right);st.push(node->left);}}return result;}
};

后序遍历

前序遍历是“中左右”,在后续遍历中先变成“中右左”,得到数组结果再反转即可得到“左右中”的后序遍历

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;st.push(root);while(!st.empty()){TreeNode* node = st.top();st.pop();if(node != nullptr){result.push_back(node->val);st.push(node->left);st.push(node->right);}}reverse(result.begin(),result.end());return result;}
};

中序遍历

与前两种遍历不同之处:

  1. while循环中增加了cur != nullptr条件 (因为存在根节点只有右子树时当栈为空,循环还不能结束)
  2. 只有再遍历至空节点时才能有出栈操作
class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;TreeNode* cur = root;if(root != nullptr) st.push(root);while(cur != nullptr || !st.empty()){if(cur != nullptr){if(cur != root)st.push(cur);cur = cur->left;}else{TreeNode* node = st.top();st.pop();result.push_back(node->val);cur = node->right;}}return result;}
};

二叉树的统一迭代法

核心思想:将每次要处理的节点(当前树下是中节点)放入栈后再向栈中加一个null值作为标记 ;

巧记:由于栈有后进先出特点,所有处理顺序应与遍历顺序相反

前序遍历

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) {st.pop();if (node->right) st.push(node->right);  // 右if (node->left) st.push(node->left);    // 左st.push(node);                          // 中st.push(NULL);} else {st.pop();node = st.top();st.pop();result.push_back(node->val);}}return result;}
};

 

后序遍历

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) {st.pop();st.push(node);                          // 中st.push(NULL);if (node->right) st.push(node->right);  // 右if (node->left) st.push(node->left);    // 左} else {st.pop();node = st.top();st.pop();result.push_back(node->val);}}return result;}
};

中序遍历

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) {st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中if (node->right) st.push(node->right);  // 添加右节点(空节点不入栈)st.push(node);                          // 添加中节点st.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。if (node->left) st.push(node->left);    // 添加左节点(空节点不入栈)} else { // 只有遇到空节点的时候,才将下一个节点放进结果集st.pop();           // 将空节点弹出node = st.top();    // 重新取出栈中元素st.pop();result.push_back(node->val); // 加入到结果集}}return result;}
};

二叉树的层序遍历

视频讲解:讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历_哔哩哔哩_bilibili

 递归代码:

引入一个深度变量 ,由深度决定当前层级

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);order(cur->right,result,depth+1);}vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;int depth = 0;order(root,result,depth);return result;}
};

 

迭代代码:

关键:使用队列数据结构,并引入一个计数变量,用来决定每次出队列的元素个数 。每出队一个元素,就将其左右子孩入队列。

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;queue<TreeNode*> q;if(root) q.push(root);while(!q.empty()){int sz = q.size();vector<int> v;while(sz--){TreeNode* node = q.front();q.pop();if(node != nullptr){v.push_back(node->val);if(node->left) q.push(node->left);if(node->right) q.push(node->right);}}result.push_back(v);}return result;}
};

使用迭代代码解决如下10题易如反掌:

102.二叉树的层序遍历 --直接cv上述代码

107.二叉树的层次遍历II--将结果二维数组反转即可

199.二叉树的右视图--遍历结果二维数组只取每一维中最后一个元素

637.二叉树的层平均值--遍历结果二维数组并对每一维元素求平均值

429.N叉树的层序遍历--把之前循环中两个子节点换成多节点,并通过for循环方式入队列

515.在每个树行中找最大值--通过双重循环,对二维数组结果中每一维找最大值

116.填充每个节点的下一个右侧节点指针--每一层遍历时先用数组保存出队列节点,从第二个节点起让数组中最后一个元素next指针指向该节点

117.填充每个节点的下一个右侧节点指针II--同上,代码不变

104.二叉树的最大深度--每次while循环最后加上depth++

111.二叉树的最小深度--在上题基础上加一个判断条件:if(node->left == nullptr && node->right == nullptr),当达到该条件,就跳出while循环

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

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

相关文章

【2025留学】德国留学真的很难毕业吗?为什么大家不来德国留学?

大家好&#xff01;我是德国Viviane&#xff0c;一句话讲自己的背景&#xff1a;本科211&#xff0c;硕士在德国读的电子信息工程。 之前网上一句热梗&#xff1a;“德国留学三年将是你人生五年中最难忘的七年。”确实&#xff0c;德国大学的宽进严出机制&#xff0c;延毕、休…

PHP多场地预定小程序系统源码

一键畅游多地&#xff01;多场地预定小程序的超实用指南 段落一&#xff1a;【开篇&#xff1a;告别繁琐&#xff0c;预订新体验】 &#x1f389;&#x1f680; 还在为多个活动或会议的场地预订而头疼不已吗&#xff1f;多场地预定小程序来拯救你啦&#xff01;它像是一位贴心…

基于Element UI内置的Select下拉和Tree树形组件,组合封装的树状下拉选择器

目录 简述 效果 功能描述 代码实现 总结 简述 基于Element UI内置的Select下拉和Tree树形组件&#xff0c;组合封装的树状下拉选择器。 效果 先看效果&#xff1a; 下拉状态&#xff1a; 选择后状态&#xff1a; 选择的数据&#xff1a; 功能描述 1、加载树结构&…

FastAPI(七十八)实战开发《在线课程学习系统》接口开发-- 评论

源码见&#xff1a;"fastapi_study_road-learning_system_online_courses: fastapi框架实战之--在线课程学习系统" 梳理下思路 1.判断是否登录 2.课程是否存在 3.如果是回复&#xff0c;查看回复是否存在 4.是否有权限 5.发起评论 首先新增pydantic模型 class Cour…

Git勤勉 两种方式上传

官网 勤勉Gitea 创建仓库 上传代码 可以先取个仓库名字 给个分支的名字就可以创建了 创建好了会出现一个链接 复制这个链接 打开要上传的项目 删除.idea/target/iml文件 cmd打开小黑窗 输入这个命令 初始化 添加仓库缓存 git init git xxx 把刚刚复制的链接放上去 gi…

【深度学习】大模型GLM-4-9B Chat ,微调与部署(3) TensorRT-LLM、TensorRT量化加速、Triton部署

文章目录 获取TensorRT-LLM代码&#xff1a;构建docker镜像并安装TensorRT-LLM&#xff1a;运行docker镜像&#xff1a;安装依赖魔改下部分package代码&#xff1a;量化&#xff1a;构建图&#xff1a;全局参数插件配置常用配置参数 测试推理是否可以代码推理CLI推理 性能测试小…

pyqt designer使用spliter

1、在designer界面需要使用spliter需要父界面不使用布局&#xff0c;减需要分割两个模块选中&#xff0c;再点击spliter分割 2、在分割后&#xff0c;再对父界面进行布局设置 3、对于两边需要不等比列放置的&#xff0c;需要套一层 group box在最外层进行分割

从善如流之您最亲近人之善,肯出力之象-下学而上达

您最亲近人之善&#xff0c;肯出力之象&#xff0c;就是那个爬&#xff0c;甚至于跪倒在地上&#xff0c;抹那个下水井子。这或许就是那个马云大佬讲过的&#xff0c;就是从您最近距离&#xff0c;身边的人学习。人家为啥做的好&#xff0c;出色&#xff1f;而且您是一母同胞之…

基于微信小程序+SpringBoot+Vue的网络安全科普系统(带1w+文档)

基于微信小程序SpringBootVue的网络安全科普系统(带1w文档) 基于微信小程序SpringBootVue的网络安全科普系统(带1w文档) 优质的网络安全科普系统不仅可以单纯的满足工作人员管理的日常工作需求&#xff0c;还可以满足用户的需求。可以降低工作人员的工作压力&#xff0c;提高效…

LeetCode刷题笔记第682题:棒球比赛

LeetCode刷题笔记第682题&#xff1a;棒球比赛 题目&#xff1a; 想法&#xff1a; 遍历输入的列表&#xff0c;按照规则将分数和操作依次进行&#xff0c;存储在新建的列表中&#xff0c;最终输出列表中的元素和&#xff0c;代码如下&#xff1a; class Solution:def calPo…

网安零基础入门神书,全面介绍Web渗透核心攻击与防御方式!

Web安全是指Web服务程序的漏洞&#xff0c;通常涵盖Web漏洞、操作系统洞、数据库漏洞、中间件漏洞等。 “渗透测试”作为主动防御的一种关键手段&#xff0c;对评估网络系统安全防护及措施至关重要&#xff0c;因为只有发现问题才能及时终止并预防潜在的安全风险。 根据网络安…

第6篇文献研读生态廊道相关综述

该文发在生态与农村环境学报。该文章写了生态廊道概念的发展历程、生态廊道类型及功能、生态廊道划定的理论和方法、生态廊道的时间和国内大型生态廊道建设实践。 这篇文章可以让大家了解生态廊道的知识。

C语言实现K均值聚类

K均值聚类(K_means)基础理论 K_means聚类是一种简单且广泛使用的聚类算法&#xff0c;它旨在将数据集中的样本划分为k个不同的聚类&#xff0c;其中k是事先指定的聚类数量&#xff0c;该算法的核心思想是迭代地优化聚类中心&#xff0c;以最小化每个样本与其所属聚类中心之间的…

懂个锤子Vue 项目工程化进阶⏫:

Vue项目工程化进阶⏫&#xff1a; 前言&#xff1a; 紧跟前文&#xff0c;目标学习Vue2.0——3.0&#xff1a; 懂个锤子Vue、WebPack5.0、WebPack高级进阶 涉及的技术栈… 当然既然学习框架的了&#xff0c;HTMLCSSJS三件套必须的就不说了&#xff1a; JavaScript 快速入门 …

react中如何mock数据

1.需求说明 因为前后端分离开发项目&#xff0c;就会存在前端静态页面写好了&#xff0c;后端数据接口还没写好&#xff1b;这时候前端就需要自己定义数据来使用。 定义数据有三种方式&#xff1a;直接写死数据、使用mock软件、json-server工具 这里讲解通过json-server工具…

面向对象程序设计(C++)模版初阶

1. 函数模版 1.1 函数模版概念 函数模板代表了一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用时被参数化&#xff0c;根据实参类型产生函数的特定类型版本&#xff0c;可以类比函数参数&#xff0c;函数模版就是将函数参数替换为特定类型版本 1.2 函数模版格…

基于ant-design-vue3多功能操作表格,表头序号为动态添加记录按钮,鼠标在表格记录行,当前行序号显示删除按钮

由于项目需要&#xff0c;并考虑到尽可能让空间利用率高&#xff0c;因此定制开发一个表格组件&#xff0c;组件功能主要是在序号表头位置为添加按钮&#xff0c;点击按钮&#xff0c;新增一行表格数据&#xff1b;表格数据删除不同于以往表格在操作栏定义删除按钮&#xff0c;…

问题解决|如何优雅展示层级或关联数据?

一、8种可用图表类型及配套教程 &#xff08;一&#xff09;包珠图 &#xff08;1&#xff09;功能介绍 包珠图&#xff08;Circular Packing&#xff09;&#xff0c;是一类较特殊的分类树状图&#xff0c;以气泡之间的包含关系展示层级关系&#xff0c;以气泡面积&#xf…

Spring事件机制

文章目录 一、Spring事件二、实现Spring事件1、自定义事件2、事件监听器2.1 实现ApplicationListener接口2.2 EventListener2.3 TransactionalEventListener 3、事件发布4、异步使用 三、EventBus1、事件模式2、EventBus三要素3、同步事件3.1 定义事件类3.2 定义事件监听3.3 测…

解析西门子PLC的String和WString

西门子PLC有两种字符串类型&#xff0c;String与WString String 用于存放英文数字标点符号等ASCII字符&#xff0c;每个字符占用一个字节 WString宽字符串用于存放中文、英文、数字等Unicode字符&#xff0c;每个字符占用两个字节 之前我搞过一篇解析String的 关于使用TCP-…