代码随想录day12 | [前、中、后、层]二叉树的遍历迭代法和递归法

news/2024/11/29 2:31:02/

文章目录

    • 一、前后中序递归法
    • 二、前后序迭代法
    • 三、中序遍历迭代法
    • 四、层序遍历

递归三部曲:
1️⃣ 第一步确定递归函数的返回值和参数
2️⃣第二步确定递归的终止条件
3️⃣第三步确定单层递归处理的逻辑

一、前后中序递归法

前序遍历二叉树

class Solution
{
private:vector<int> res;public:void dfs(TreeNode *root){if (root == nullptr)return;res.push_back(root->val);if (root->left)preorderTraversal(root->left);if (root->right)preorderTraversal(root->right);}vector<int> preorderTraversal(TreeNode *root){dfs(root);return res;}
};

二、前后序迭代法

前序遍历二叉树
借助栈来实现。
在这里插入图片描述


按理说应该是:根 左 右
但是是栈的结构,所以入孩子节点的时候,先右再左。
这样方便弹出!
在这里插入图片描述

前序遍历非递归:
class Solution
{
public:vector<int> preorderTraversal(TreeNode *root){// 迭代法vector<int> res;stack<TreeNode *> st;if (root == nullptr)return res;st.push(root);while (!st.empty()){// 每次进入循环需要先获得栈顶元素TreeNode *tmp = st.top(); // 根st.pop();res.push_back(tmp->val);if (tmp->right)st.push(tmp->right); // 右if (tmp->left)st.push(tmp->left); // 左}return res;}
};

前序遍历改为后序遍历只需要改2行,再加一行即可。
右左换一下顺序,再逆置一下res数组即可得到我们的答案。

后序遍历非递归:
class Solution
{
public:vector<int> preorderTraversal(TreeNode *root){// 迭代法vector<int> res;stack<TreeNode *> st;if (root == nullptr)return res;st.push(root);while (!st.empty()){// 每次进入循环需要先获得栈顶元素TreeNode *tmp = st.top(); // 根st.pop();res.push_back(tmp->val);if (tmp->left)st.push(tmp->left); // 左if (tmp->right)st.push(tmp->right); // 右}reverse(res.begin(),res.end());return res;}
};

三、中序遍历迭代法

94.二叉树的中序遍历

为何中序遍历的非递归不同?

因为访问处理的顺序和遍历的顺序是不同的。
所以我们需要一个指针来帮助我们遍历二叉树,使用栈来处理节点上的元素。

// 中序遍历使用迭代法
class Solution
{
public:vector<int> inorderTraversal(TreeNode *root){// 迭代法vector<int> res;stack<TreeNode *> st;TreeNode *cur = root;while (cur != nullptr || !st.empty()){if (cur != nullptr){st.push(cur);cur = cur->left; // 左}else{// cur==nullptr 那么把cur指向栈顶元素岂不是更方便迭代?cur = st.top();st.pop();res.push_back(cur->val); // 根cur = cur->right;        // 右}}return res;}
};

四、层序遍历

102.二叉树的层序遍历
要使用队列。

class Solution
{
public:vector<vector<int>> levelOrder(TreeNode *root){vector<vector<int>> res;queue<TreeNode *> q;if (root != nullptr)q.push(root);while (!q.empty()){int size = q.size();vector<int> v;for (int i = 0; i < size; i++){// 每次进入循环,都需要一个迭代变量TreeNode *tmp = q.front();q.pop(); // 每次弹出的元素就是要记录到数组的元素v.push_back(tmp->val);// 将左右孩子 加入队列if (tmp->left)q.push(tmp->left);if (tmp->right)q.push(tmp->right);}res.push_back(v);}return res;}
};

1、while() 结束条件?

当队列为空时,说明遍历完了,第一次不管三七二十一肯定是把根直接入队列。

2、为何要记录size?

因为我们不记录的话,就不知道一层树中节点数量,那么就不知道一层循环队列该弹出多少元素。

3、内层循环每次都要定义一个tmp节点?

每次循环都要定义一个节点获取我们的队头元素,方便我们每次操作这个元素,然后再把它弹出。


http://www.ppmy.cn/news/978006.html

相关文章

Spring Boot单元测试入门指南

Spring Boot单元测试入门指南 JUnit是一个成熟和广泛应用的Java单元测试框架&#xff0c;它提供了丰富的功能和灵活的扩展机制&#xff0c;可以帮助开发人员编写高质量的单元测试。通过JUnit&#xff0c;开发人员可以更加自信地进行重构、维护和改进代码&#xff0c;同时提高代…

KubeVela篇05:为kubevela开发terraform-mycloud Addon插件

通过前面的章节,我们已经学习了解terraform,并通过vpc资源例子,为私有云/混合云开发了terraform provider,这一节介绍如何将我们开发的mycloud terraform provider整合到kubevela控制平台上,以通过在application中声明一个kubevela组件的方式去申请基础设施资源。 我们需…

vue、vuex、vue-router初学导航配合elementui及vscode快捷键

目录 一、vue资源 1.vue知识库汇总 2.vuejs组件 3.Vue.js 组件编码规范 目标 #目录 #基于模块开发

【数字信号处理】带通采样定理及其MATLAB仿真

目录 一、带通采样定理1.1 内容1.2 公式推导 二、MATLAB信号仿真2.1 信号仿真实验2.2 MATLAB代码 三、总结参考 一、带通采样定理 按照奈奎斯特采样定理(低通采样)&#xff0c;采样频率 f s f_{s} fs​ 要大于等于信号中最高频率 f m a x f_{max} fmax​ 的2倍&#xff0c;才…

【Spring Cloud】Ribbon 中的几种负载均衡策略

文章目录 前言一、Ribbon 介绍二、负载均衡设置三、7种负载均衡策略3.1.轮询策略3.2.权重策略3.3.随机策略3.4.最小连接数策略3.5.重试策略3.6.可用性敏感策略3.7.区域敏感策略 前言 负载均衡通常有两种实现手段&#xff0c;一种是服务端负载均衡器&#xff0c;另一种是客户端…

前端:运用html+css+js模仿百度热搜电影榜鼠标移入特效

前端:运用htmlcssjs模仿百度热搜电影榜鼠标移入特效 1. 实现原理2. 界面布局3. js实现对鼠标移入和移出的监听4. 参考代码如下&#xff1a; 1. 实现原理 百度热搜上电影榜鼠标移入特效如上图所示。个人觉得上述特效实现原理为使用相对定位、绝对定位实现的(鼠标移入和没有移入…

23 自定义控件

案例&#xff1a;组合Spin Box和Horizontal Slider实现联动 新建Qt设计师界面&#xff1a; 选择Widget&#xff1a; 选择类名&#xff08;生成.h、.cpp、.ui文件&#xff09; 在smallWidget.ui中使用Spin Box和Horizontal Slider控件 可以自定义数字区间&#xff1a; 在主窗口w…

华为认证HCIA-HCIP-HCIEdatacom题库解析+机构视频+实验

题库包含有2023年最新HCIA-datacom题库、HCIP-datacom题库&#xff0c;HCIE-datacom题库&#xff0c; 云计算HCIA&#xff0c;HCIP题库&#xff0c;云服务HCIA&#xff0c;HCIP题库&#xff0c;华为存储HCIP题库&#xff0c;华为安全HCIP题库 &#xff0c;学习笔记&#xff0c;…