题目

给定一个二叉树,返回它的中序 遍历。

示例:

输入: [1,null,2,3]
1
\
2
/
3 输出: [1,3,2]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?


考点

stack

递归

中序遍历:左-根-右


思路

ref:二叉树的前中后和层序遍历详细图解(递归和非递归写法)

1.递归

若根节点为空,返回。左子树调用递归。输出根节点。右子树调用递归。

2.非递归,用栈

从根节点开始,先将根节点压入栈,然后再将其所有左子结点压入栈,然后取出栈顶节点,保存节点值,再将当前指针移到其右子节点上,若存在右子节点,则在下次循环时又可将其所有左子结点压入栈中。这样就保证了访问顺序为左-根-右。

3.线索二叉树

ref:Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)

wiki:Threaded binary tree

A binary tree is threaded by making all right child pointers that would normally be null point to the inorder successor of the node (if it exists), and all left child pointers that would normally be null point to the inorder predecessor of the node.

把所有原本为空的右子节点指向了中序遍历之后的那个节点,

把所有原本为空的左子节点指向了中序遍历之前的那个节点,

构建一个线索二叉树,我们需要将所有为空的右子节点指向中序遍历的下一个节点,这样我们中序遍历完左子结点后,就能顺利的回到其根节点继续遍历了。

1. 初始化指针cur指向root

2. 当cur不为空时

  - 如果cur没有左子结点

      a) 打印出cur的值

    b) 将cur指针指向其右子节点

  - 反之

     将pre指针指向cur的左子树中的最右子节点 

     * 若pre不存在右子节点

          a) 将其右子节点指回cur

        b) cur指向其左子节点

     * 反之

      a) 将pre的右子节点置空

      b) 打印cur的值

      c) 将cur指针指向其右子节点


代码

1.递归

//递归:对左子节点调用递归,访问根,对右子树调用递归
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ret;
order(root,ret);
return ret;
} void order(TreeNode* root,vector<int>& ret)
{
if(!root) return;
order(root->left,ret);
ret.push_back(root->val);
order(root->right,ret);
}
};

2.非递归+栈

//非递归:用栈
//1.先从根节点开始,遍历左子树,把经过的节点都压入栈,直到p到达最左节点。
//2.将栈顶元素输出,把当前节点指向栈顶元素右节点,弹出栈顶元素。
//3.如果当前节点存在或者栈不为空,循环1,2步骤,
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ret;
stack<TreeNode*> s;
TreeNode* curNode=root;
while(curNode||!s.empty())//迭代条件:栈不为空,且还有节点没访问到
{
//遍历所有left,经历过的全入栈,找到最左节点
while(curNode)
{
s.push(curNode);
curNode=curNode->left;
} //由于最左节点没有左子树,所以相当于是子结构树的根节点,中序遍历再访问右子树,重复1,2步 //得到最左节点(栈顶)
curNode=s.top();
//输出最左节点
ret.push_back(curNode->val);
//出栈
s.pop(); //访问最左节点的右子树
curNode=curNode->right;
}
return ret;
}
};

3.看不懂的解法。线索二叉树。

// Non-recursion and no stack
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> res;
if (!root) return res;
TreeNode *cur, *pre;
cur = root;
while (cur) {
if (!cur->left) {
res.push_back(cur->val);
cur = cur->right;
} else {
pre = cur->left;
while (pre->right && pre->right != cur) pre = pre->right;
if (!pre->right) {
pre->right = cur;
cur = cur->left;
} else {
pre->right = NULL;
res.push_back(cur->val);
cur = cur->right;
}
}
}
return res;
}
};

问题

LeetCode94. Binary Tree Inorder Traversal的更多相关文章

  1. (二叉树 递归) leetcode94. Binary Tree Inorder Traversal

    Given a binary tree, return the inorder traversal of its nodes' values. Example: Input: [1,null,2,3] ...

  2. LeetCode94 Binary Tree Inorder Traversal(迭代实现) Java

    题目: Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binar ...

  3. Leetcode94. Binary Tree Inorder Traversal二叉树的中序遍历(两种算法)

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

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

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

  5. LintCode Binary Tree Inorder Traversal

    Binary Tree Inorder Traversal Given a binary tree, return the inorder traversal of its nodes' values ...

  6. 37. Binary Tree Zigzag Level Order Traversal && Binary Tree Inorder Traversal

    Binary Tree Zigzag Level Order Traversal Given a binary tree, return the zigzag level order traversa ...

  7. 3月3日(4) Binary Tree Inorder Traversal

    原题: Binary Tree Inorder Traversal 和 3月3日(2) Binary Tree Preorder Traversal 类似,只不过变成中序遍历,把前序遍历的代码拿出来, ...

  8. 49. leetcode 94. Binary Tree Inorder Traversal

    94. Binary Tree Inorder Traversal    二叉树的中序遍历 递归方法: 非递归:要借助栈,可以利用C++的stack

  9. LeetCode: Binary Tree Inorder Traversal 解题报告

    Binary Tree Inorder Traversal Given a binary tree, return the inorder traversal of its nodes' values ...

随机推荐

  1. ErlangC 最佳人力效益指标

    以平均服务时间(AHT)180秒,顾客来电量每15分钟150通以及服务目标时间在20秒内为例子说明最佳人力效益指标.此假设条件下由Erlang C模拟器的结果如下图, 假设我希望客服中心的期望服务水准 ...

  2. Spring Boot实战(2) Spring常用配置

    1. Bean的Scope scope描述Spring容器如何新建Bean的实例.通过注解@Scope实现,取值有: a. Singleton:一个Spring容器中只有一个Bean的实例.此为Spr ...

  3. js中 var functionName = function() {} 和 function functionName() {} 两种函数声明的区别 (译)

    stackOverflow中看到了很久以前问的一个关于函数声明的问题,问题对函数剖析的特别深.这里翻译了一下组织成一篇小博文,加深一下对这两种声明方式的印象.虽是老调重弹,但是只要能帮助理解问题,不管 ...

  4. Redis整理第二波(启动、命令)

    启动 配置数据库数量: Redis默认开启16个数据库,不能像mysql自定义数据库名称,只能是数值,不能修改. 配置内存大小: 会生成一个和内存大小一样的文件. maxmemory 200mb #在 ...

  5. 从零开始的全栈工程师——js篇(cookie)

    Cookie是由服务器端生成,发送给User-Agent,浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器,对cookie知识感兴 ...

  6. python基础:冒泡和选择排序算法实现

    冒泡排序和选择排序   首先引用一下百度百科对于冒泡算法的定义:   冒泡排序算法的原理如下: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素做同样的工作,从开始第一对到结尾 ...

  7. 《Cron表达式详解》

    Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: Seconds Minutes Hours DayofMonth Month ...

  8. 轻松完成excel读写操作- 基于POI的框架BingExcel的使用(2)

    在进行 类转换时候,系统默认注册了一些转换器,当然你也可以自定局部或者全局的转换器.下面进行具体使用说明  java类说明 对应的java实体类,其属性必须要有__@CellConfig__注解,此注 ...

  9. 转:Oracle优化总结

    本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了 ORACLE数据库的优化调整方案. 关键词 ORACLE数据库 环境 ...

  10. 【起航计划 004】2015 起航计划 Android APIDemo的魔鬼步伐 03 App->Activity->Animation Activity跳转动画 R.anim.×× overridePendingTransition ActivityOptions类

    App->Activity->Animation示例用于演示不同Activity切换时动态效果. android 5.0例子中定义了6种动画效果: 渐变Fade In 缩放Zoom In ...