二叉树的中序遍历
876 字
4 分钟
二叉树的中序遍历
题目链接:94. 二叉树的中序遍历 - 力扣(LeetCode)
- 难度:简单
- 标签:树、深度优先搜索、二分查找、二叉树
题目描述
Note
原题说明:
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
示例 1
graph TD
1((1)) --> null1[null]
1((1)) --> 2((2))
2((2)) --> 3((3))
2((2)) --> null2[null]
style null1 fill:none,stroke:none
style null2 fill:none,stroke:none
输出:[1, 3, 2]
遍历基础复习
二叉树的常见遍历顺序如下:
- 先序遍历 (Preorder):根 → 左 → 右
- 中序遍历 (Inorder):左 → 根 → 右
- 后序遍历 (Postorder):左 → 右 → 根
方案一:递归解法(最直观)
核心思路: 利用函数调用栈,在处理当前节点前先递归访问左子树,处理完后再递归访问右子树。
源码实现
class Solution {public: vector<int> inorderTraversal(TreeNode* root) { vector<int> ans; dfs(root, ans); return ans; }private: void dfs(TreeNode* node, vector<int>& out) { if (!node) return; dfs(node->left, out); // 左 out.push_back(node->val); // 根 dfs(node->right, out); // 右 }};复杂度分析
- 时间复杂度:。 是节点总数。
- 空间复杂度:。在最坏情况下(树呈链状),递归深度可达 。
方案二:迭代解法(手动维护栈)
核心思路:
为了避免系统递归栈过深,我们可以自己手动维护一个 stack。
- 一路向左:将所有遇到的左孩子压入栈中。
- 弹栈访问:当左边到头时,弹出栈顶节点并读取。
- 转向右侧:对右孩子重复上述过程。
源码实现
#include <stack>#include <vector>
class Solution {public: vector<int> inorderTraversal(TreeNode* root) { vector<int> ans; stack<TreeNode*> st; TreeNode* cur = root;
while (cur || !st.empty()) { // 阶段 1: 一路向左压栈 while (cur) { st.push(cur); cur = cur->left; } // 阶段 2: 弹栈并读取 cur = st.top(); st.pop(); ans.push_back(cur->val); // 阶段 3: 转向右子树 cur = cur->right; } return ans; }};复杂度分析
- 时间复杂度:。
- 空间复杂度:。栈的大小取决于树的高度。
方案三:Morris 遍历( 空间神技)
核心思路:
利用二叉树中大量空闲的指针(叶子节点的 right 指针)来建立特殊的连接(线索),从而在不使用栈的情况下实现回溯。
- 建立线索:在移动到左子树前,让左子树的最右侧节点(当前节点的前驱)指向当前节点。
- 拆除线索:当再次回到当前节点时,说明左子树已处理完,恢复指针并输出当前值。
源码实现
class Solution {public: vector<int> inorderTraversal(TreeNode* root) { vector<int> ans; TreeNode *cur = root, *pre; while (cur) { if (cur->left) { // 寻找左子树的最右节点(前驱) pre = cur->left; while (pre->right && pre->right != cur) pre = pre->right;
if (!pre->right) { pre->right = cur; // 建立回勾线索 cur = cur->left; continue; // 继续向左探路 } else { pre->right = nullptr; // 任务完成,拆除线索 } } ans.push_back(cur->val); // 访问根节点 cur = cur->right; // 向右(真子结点或回勾) } return ans; }};复杂度分析
- 时间复杂度:。虽然有
while嵌套,但每个边最多被访问两次。 - 空间复杂度:。没有任何辅助栈或开销。
总结
- 递归 vs 迭代:递归代码简洁,迭代更贴合计算机底层逻辑。
- 中序特性:中序遍历二叉搜索树(BST)得到的是一个递增的有序序列。
- 高级技巧:Morris 遍历虽然在工业实践中不常用(会短暂破坏树结构),但在算法面试中是体现深度的绝佳话题。
Important
掌握了中序遍历的这三种姿势,二叉树的遍历逻辑你就已经彻底通关了!
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
最后更新于 2025-10-23,距今已过 188 天
部分内容可能已过时
相关文章 智能推荐
1
对称二叉树
算法 力扣第101题:对称二叉树。深入理解树的镜像对称性质,掌握递归与迭代两种姿势下的双向比对技巧。
2
二叉树的层序遍历
算法 力扣第102题:二叉树的层序遍历。掌握广度优先搜索(BFS)的核心机制,学习如何按层级剥开树结构的逻辑脉络。
3
二叉树的层序遍历 II
算法 力扣第107题:二叉树的层序遍历 II。在层序遍历的基础上,学习如何通过简单的结果反转实现自底向上的层级展示。
4
二叉树的最大深度
算法 力扣第104题:二叉树的最大深度。深入理解递归与广度优先搜索(BFS)在计算树结构深度时的应用场景。
5
相同的树
算法 力扣第100题:相同的树。利用深度优先搜索(DFS)的递归特性,优雅地判断两棵二叉树的结构与数值一致性。
随机文章 随机推荐