1. 题目

2. 解答

2.1. 递归法

定义一个存放树中数据的向量 data,从根节点开始,如果节点不为空,那么

    1. 递归得到其左子树的数据向量 temp,将 temp 合并到 data 中去
    1. 将当前节点的数值加入到 data 中
    1. 递归得到其右子树的数据向量 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,从根节点开始,如果节点不为空或者栈非空,循环以下过程:

    1. 如果节点非空,将节点压入栈,节点指向其左孩子,循环直到节点为空
    1. 如果节点为空,弹出栈顶节点,将节点的值加入 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,从根节点开始,如果当前节点非空,循环以下过程:

    1. 如果当前节点没有左孩子,将当前节点的值加入到 data 中,当前节点指向其右孩子
    1. 如果当前节点有左孩子,则寻找当前节点的前驱节点,即节点值小于该节点值并且值最大的节点,也即当前节点左子树中值最大的节点
    • 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 ——二叉树的中序遍历的更多相关文章

  1. LeetCode 94. 二叉树的中序遍历(Binary Tree Inorder Traversal)

    94. 二叉树的中序遍历 94. Binary Tree Inorder Traversal 题目描述 给定一个二叉树,返回它的 中序 遍历. LeetCode94. Binary Tree Inor ...

  2. Java实现 LeetCode 94 二叉树的中序遍历

    94. 二叉树的中序遍历 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? / ...

  3. Leetcode 94. 二叉树的中序遍历

    1.问题描述 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 2.解法一 ...

  4. LeetCode 94. 二叉树的中序遍历(Binary Tree Inorder Traversal)

    题目描述 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路 由于 ...

  5. leetcode 94二叉树的中序遍历

    递归算法C++代码: /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; ...

  6. 【leetcode 94. 二叉树的中序遍历】解题报告

    前往二叉树的:前序,中序,后序 遍历算法 方法一:递归 vector<int> res; vector<int> inorderTraversal(TreeNode* root ...

  7. 【LeetCode】94. 二叉树的中序遍历

    94. 二叉树的中序遍历 知识点:二叉树:递归:Morris遍历 题目描述 给定一个二叉树的根节点 root ,返回它的 中序 遍历. 示例 输入:root = [1,null,2,3] 输出:[1, ...

  8. Leetcode题目94.二叉树的中序遍历(中等)

    题目描述: 给定一个二叉树,返回它的中序遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 思路解析: 1 ...

  9. leetcode刷题-94二叉树的中序遍历

    题目 给定一个二叉树,返回它的中序 遍历. 实现 # def __init__(self, x): # self.val = x # self.left = None # self.right = N ...

随机推荐

  1. Linux -- 用户组篇

    Linux -- 用户与用户组 1.Linux 系统中有三种角色:所有者(用户),用户组与其他人,一张图可以说明用户与用户组的关系. 如图,某公司相当于一个用户组,该用户组下有A,B两个用户,用户拥有 ...

  2. Webstorm设置代码提示

    下载路径: https://github.com/virtoolswebplayer/ReactNative-LiveTemplate 本插件可以配合Webstorm设置代码提示. Mac下安装 We ...

  3. div样式position:fixed,不随屏幕滚动而滚动,导致屏幕太小时弹出层被遮挡,无法滚动查看的解决办法

    window.onscroll = function () { var sl = -Math.max(document.body.scrollTop, document.documentElement ...

  4. hdu_5187_zhx's contest

    Problem Description As one of the most powerful brushes, zhx is required to give his juniors n probl ...

  5. react组件间传值详解

    一.父子组件间传值     <1>父传子         父组件:

  6. CI框架视图继承

    CI(CodeIgniter)框架 视图继承 这个代码不是我撸的 ... 当时在哪儿找的忘了 ... 如果有侵权什么的 ... 联系我删了 ... 需要去core里面创建一个MY_loader.php ...

  7. Delphi 拦截滚轮事件不响应滚轮的上下滚动

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  8. 详解 Python3 正则表达式(一)

    本文翻译自:https://docs.python.org/3.4/howto/regex.html 博主对此做了一些批注和修改 ^_^ 正则表达式介绍 正则表达式(Regular expressio ...

  9. OpenWrt超时检测

    参考http://www.right.com.cn/forum/thread-261702-1-1.html vim /home/ihid/chaos_calmer/feeds/luci/module ...

  10. 『Linux基础 - 2 』操作系统,Linux背景知识和Ubuntu操作系统安装

    这篇笔记记录了以下几个知识点: 1.目前常见的操作系统及分类,虚拟机 2.Linux操作系统背景知识,Windows和Linux两个操作系统的对比 3.在虚拟机中安装Ubuntu系统的详细步骤 OS( ...