LeetCode 94 ——二叉树的中序遍历
1. 题目

2. 解答
2.1. 递归法
定义一个存放树中数据的向量 data,从根节点开始,如果节点不为空,那么
- 递归得到其左子树的数据向量 temp,将 temp 合并到 data 中去
- 将当前节点的数值加入到 data 中
- 递归得到其右子树的数据向量 temp,将 temp 合并到 data 中去
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> data = {};
vector<int> temp = {};
if (root != NULL)
{
temp = inorderTraversal(root->left);
data.insert(data.end(),temp.begin(),temp.end());
data.push_back(root->val);
temp = inorderTraversal(root->right);
data.insert(data.end(),temp.begin(),temp.end());
}
return data;
}
};
2.2. 迭代法
定义一个存放树中节点的栈 node_stack 和存放数据的向量 data,从根节点开始,如果节点不为空或者栈非空,循环以下过程:
- 如果节点非空,将节点压入栈,节点指向其左孩子,循环直到节点为空
- 如果节点为空,弹出栈顶节点,将节点的值加入 data,然后将节点指向其右孩子
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> data = {};
stack<TreeNode*> node_stack;
TreeNode* temp = root;
while (temp || !node_stack.empty())
{
while(temp != NULL)
{
node_stack.push(temp);
temp = temp->left;
}
temp = node_stack.top();
node_stack.pop();
data.push_back(temp->val);
temp = temp->right;
}
return data;
}
};
2.3. Morris 遍历法
前面两种方法要么需要函数栈要么需要人工栈,其空间复杂度为 \(O(n)\),而 Morris 遍历法可以做到在不影响时间复杂度的情况下做到空间复杂度为 \(O(1)\)。
定义一个存放数据的向量 data,从根节点开始,如果当前节点非空,循环以下过程:
- 如果当前节点没有左孩子,将当前节点的值加入到 data 中,当前节点指向其右孩子
- 如果当前节点有左孩子,则寻找当前节点的前驱节点,即节点值小于该节点值并且值最大的节点,也即当前节点左子树中值最大的节点
- a) 如果前驱节点没有右孩子,前驱节点右孩子指向当前节点,当前节点指向其左孩子
- b) 如果前驱节点右孩子为当前节点,将当前节点的值加入到 data 中,当前节点指向其右孩子,前驱节点右孩子设为空(恢复原有树结构)

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> data = {};
TreeNode* cur = root;
TreeNode* pre = NULL;
while (cur)
{
if (cur->left == NULL)
{
data.push_back(cur->val);
cur = cur->right;
}
else
{
// 寻找前驱结点
pre = cur->left;
while (pre->right != cur && pre->right)
{
pre = pre->right;
}
if (pre->right == NULL)
{
pre->right = cur;
cur = cur->left;
}
else
{
data.push_back(cur->val);
cur = cur->right;
pre->right = NULL;
}
}
}
return data;
}
};
获取更多精彩,请关注「seniusen」!

LeetCode 94 ——二叉树的中序遍历的更多相关文章
- LeetCode 94. 二叉树的中序遍历(Binary Tree Inorder Traversal)
94. 二叉树的中序遍历 94. Binary Tree Inorder Traversal 题目描述 给定一个二叉树,返回它的 中序 遍历. LeetCode94. Binary Tree Inor ...
- Java实现 LeetCode 94 二叉树的中序遍历
94. 二叉树的中序遍历 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? / ...
- Leetcode 94. 二叉树的中序遍历
1.问题描述 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 2.解法一 ...
- LeetCode 94. 二叉树的中序遍历(Binary Tree Inorder Traversal)
题目描述 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路 由于 ...
- leetcode 94二叉树的中序遍历
递归算法C++代码: /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; ...
- 【leetcode 94. 二叉树的中序遍历】解题报告
前往二叉树的:前序,中序,后序 遍历算法 方法一:递归 vector<int> res; vector<int> inorderTraversal(TreeNode* root ...
- 【LeetCode】94. 二叉树的中序遍历
94. 二叉树的中序遍历 知识点:二叉树:递归:Morris遍历 题目描述 给定一个二叉树的根节点 root ,返回它的 中序 遍历. 示例 输入:root = [1,null,2,3] 输出:[1, ...
- Leetcode题目94.二叉树的中序遍历(中等)
题目描述: 给定一个二叉树,返回它的中序遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 思路解析: 1 ...
- leetcode刷题-94二叉树的中序遍历
题目 给定一个二叉树,返回它的中序 遍历. 实现 # def __init__(self, x): # self.val = x # self.left = None # self.right = N ...
随机推荐
- Oracle中table数据数据类型
function F_ReturnDescription(varID in varchar2) return varchar2 is numDataCount ); mytable ly_family ...
- 三层架构,Struts2,SpringMVC实现原理图
三层架构,Struts2,SpringMVC实现原理图 三层架构实现原理 Struts2实现原理 SpringMVC实现原理
- JSP/Servlet开发——第八章 JSTL和EL
1. EL表达式: ●需要EL表达式的原因: ◆在JSP中使用Java脚本的局限: 1).在JSP页面中嵌入大量的Java代码: 2).访问结构比较复杂的数据时代码烦琐,且经常需要强制类型转换: eg ...
- SQL注入的浅尝辄止
简单的说,SQL注入就是通过在前端页面输入SQL语句,导致系统暴露异常信息在前端页面显示,非法者通过这些异常信息获取数据库的相干信息,为攻击系统做准备.
- Vue——关于css过渡和动画那些事
1. 单元素/组件的过渡transition Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡 条件渲染 (使用 v-if) 条件展示 (使用 v ...
- 抓包之Charles For Mac 4.0+破解版
前言:突然间发现好久没有写博客了,最近被公司的项目弄得脑壳疼
- ORALCE表的约束条件
一.主键:(PRIMARY KEY) 主键是表中的一列或多列.为表定义主键有如下几个作用: 1.主键包含的列不能输入重复的值,以此来保证一个表的所有行的唯一性: 2.主键也不允许定义此约束的列为NUL ...
- .Net Core如何在任意位置获取配置文件的内容
前几天群里有人问,我想在程序里的任意位置读取appsetting.json里的配置,该怎么搞. 话不多说上源码 首先,要想读取配置文件我们要用到IConfiguration 接口,这个接口在Start ...
- 网站用户行为分析——在Ubuntu下安装MySQL及其常用操作
安装MySQL 使用以下命令即可进行mysql安装,注意安装前先更新一下软件源以获得最新版本: sudo apt-get update #更新软件源 sudo apt-get install mysq ...
- 位域 (Bit field)
最近开始看编程之美这本书,里面有一道关于中国象棋将帅位置的简单问题,如下图所示,写一个程序输出将.帅的合法位置. 分析与解法 问题的本身并不复杂,只要把所有A.B 互相排斥的条件列举出来就可以完成本题 ...