news 2026/7/8 4:05:29

HOT100之二叉树中序遍历

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HOT100之二叉树中序遍历

递归法

当我们在函数中调用函数时,外层函数就会被操作系统暂停,然后将外层函数的状态压入系统函数调用栈中,再去执行新的函数
由于系统函数调用栈空间往往是很小的,一旦深度达到了数万层,函数调用栈就会被撑爆,导致崩溃,并且由于系统函数调用栈位于底层,每一次涉及的操作都会影响一系列底层逻辑,使得开销和运行速度大大增加

树节点定义

struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode() : val(0), left(nullptr), right(nullptr){} TreeNode(int val = 0, TreeNode* left = nullptr, TreeNode* right = nullptr) : val(val), left(left), right(right) {} };

中序遍历的遍历顺序是左节点中节点右节点(对一颗最小二叉树而言)

  • 整体思路
    一颗二叉树应该先一直迭代左节点,直至最左边的叶子节点,然后将每一个节点都当作基于该节点为根节点的一颗独立子树(非常重要,贯穿整个树)来遍历,于是将中序遍历一个最小二叉树的方法封装成一个函数来不断嵌套不断迭代
    中序遍历一颗最小二叉树函数(不唯一):
    我们开始思考该遍历函数的具体思路:
    对于一个最小二叉树(一共只有三个节点),在我们只知道根节点的情况下,要实现中序遍历,最核心的代码只有3行
    (仅作思路示范)
vector<int> res{}; void inorder(TreeNode* root) { res.push_back(root->left->val); res.push_back(root->val); res.push_back(root->right->val); }

那么如何将其运用在整颗二叉树呢?
最关键的一句话:每一个节点都当作基于该节点为根节点的一颗独立子树
所以我们需要在每一个访问左右子节点的步骤中加入迭代。
注意有空树的可能,所以要加上判断条件

void inorder(TreeNode* root, vector<int>& res) { if(root != nullptr)// { //左节点 inorder(root->left, res); //中节点 res.push_back(root->val); //右节点 inorder(root->right, res); } return; } vector<int> inorderTraversal(TreeNode* root) { vector<int> result{}; inorder(root, result); return result; }

迭代法

由于迭代法与的递归法基本原理相似(递归法使用的是隐式的函数调用栈,由系统自己维护,迭代法需要我们自己手动维护栈结构来实现)我们这道题也可以自己维护栈来代替递归法
由于栈结构由我们自己维护在堆上,所以很难发生栈溢出,同时省去系统维护带来的底层频繁创建销毁函数调用而带来的巨大开销

根据中序遍历(左->中->右),我们从根节点出发,应该先访问其左节点是否存在,若不存在则就直接录入根节点值然后再访问右节点;
若存在,注意每一个节点都当作基于该节点为根节点的一颗独立子树来处理,所以我们要先不断向左迭代,直至最左叶子节点,同时要记录向左迭代时经过的每一个节点
所以

vector<int> inorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> st; TreeNode* curr = root;//为了防止丢失整棵树的位置,我们需要用另一个节点来共同指向根节点 ...

什么条件下开始迭代处理呢?

  • 当栈中还有节点没处理即整棵树还没遍历完
  • 当前节点不为空
    但是两者之间关系又该是如何呢?无论是栈中还有节点没处理(父节点没遍历)还是当前节点不为空,可能存在子节点,只要二者满足其一就可以正常迭代
while(curr != nullptr || !st.empty()) { }

现在不断向左子节点迭代并保存,只要当前节点不为空都要向左寻找子节点

while(curr != nullptr || !st.empty()) { while(curr != nullptr) { st.push(curr); curr = curr->left; }//结束时curr == nullptr * }

此时curr为空,意味着左侧已经无路可走,我们必须利用栈顶元素(上一个路过的父节点)进行回溯
这时候根据中序遍历,由于左节点为空,所以要录入中节点st.top()->val(别忘了用完这个节点就st.pop())以及向右寻找是否存在节点

while(curr != nullptr || !st.empty()) { while(curr != nullptr) { st.push(curr); curr = curr->left; }//结束时curr == nullptr * curr = st.top(); st.pop(); res.push_back(curr->val); curr = curr->right; }

所以完整code:

vector<int> inorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; TreeNode* curr = root; while(curr != nullptr || !st.empty()) { while(curr != nullptr) { st.push(curr); curr = curr->left; } curr = st.top(); st.pop(); result.push_back(curr->val); curr = curr -> right; } return result; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/8 4:01:40

企业内网穿透管理升级:云端控制台实现流量审计与故障监控

背景&#xff1a;内网穿透为什么特别需要可观测 ZeroNews 内网穿透把企业/个人的内网服务映射到公网&#xff0c;从而赋予内网应用公网访问的能力。 然后作为一个企业级的内网穿透平台&#xff0c;公网访问只是最基础的能力&#xff0c;在后续使用过程中&#xff0c; 真正让人头…

作者头像 李华
网站建设 2026/7/8 3:57:47

Hermes Agent 训练正确阅读YApi接口文档- MiniMax-M2.1

背景 目前 Hermes Agent 使用 model&#xff1a;MiniMax-M2.1。 需求 作为一名前端开发&#xff0c;日常开发过程中&#xff0c;需要频繁写TS类型&#xff0c;目前需要 Hermes Agent 阅读接口文档后自动生成TS类型&#xff0c;提高开发效率。 要点 YApi 文档需要登录后访问&…

作者头像 李华
网站建设 2026/7/8 3:56:46

克劳夫特不等式的证明和matlab仿真实现(P124302061林宗宇)

一、引言在信源编码理论中&#xff0c;变长编码是提升编码效率的核心手段&#xff0c;通过对高概率符号分配短码字、低概率符号分配长码字&#xff0c;可使平均码长逼近信源熵极限。前缀码&#xff08;即时码&#xff09;是变长编码中最具实用价值的码型&#xff0c;其任意码字…

作者头像 李华