题目

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

示例:

输入: [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. (转)在 VMware 中安装 HMC

    在 VMware 中安装 HMC 原文:http://blog.csdn.net/ccie38499/article/details/14123493 http://www.54it.top/arch ...

  2. 修改linux文件权限命令

    修改linux文件权限命令:chmod Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作. 文件或目录的访问权限分为只读,只写和可执行三种.以文 ...

  3. ajax多次请求的一个效果思路

    首先页面加载时候显示遮罩层 jQuery(function() { show_dialog(); //tianxie(); }); 定义一个全局数组,用于存放问题id var qar = []; 循环 ...

  4. 《C#高效编程》读书笔记13-正确的初始化静态成员变量

    在创建某个类型实例之前,就应该初始化该实例的所有静态成员变量.而C#为此提供了静态初始化器和静态构造函数. 静态构造函数是特殊的构造函数,将在其他所有方法执行之前以及变量或属性被第一次访问之前执行. ...

  5. Chrome谷歌浏览器中js代码Array.sort排序的bug乱序解决办法

    [现象] 代码如下: var list = [{ n: "a", v: 1 }, { n: "b", v: 1 }, { n: "c", v ...

  6. Spring-cloud微服务 Eureka学习教程-单服务器配置之快速搭建EurekaServer、EurekaClient(基础)

    以下实例代码下载地址:https://github.com/wades2/EurekaDemo Eureka是Spring Cloud Netflix的一个子模块,也是核心模块之一.用于云端服务发现, ...

  7. Html+CSS二周目--->常用概念

    学习css几乎俩周,来总结一下 对于初学者来说,有一些基本的概念是我们应当清楚的.掌握这些概念,可以帮助你更加有效的开发,大大提高开发效率. 1.盒子模型 2.浮动(float) 3.定位(posit ...

  8. BZOJ4245: [ONTAK2015]OR-XOR(前缀和)

    题意 题目链接 Sol 又是一道非常interesting的题目 很显然要按位考虑 因为最终答案是xor之后or,所以分开之后之后这样位上1的数量是一定是偶数,否则直接加到答案里面 同时,这里面有些部 ...

  9. Mysql慢查询 [第一篇]

    一.简介 开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能. 二.参数说明 slow_query_log 慢查询开启状态slow_q ...

  10. int **a 和 int (*a)[]的区别

    关于理论知识隔壁们的教程说的很详细了我就不多赘述了.我这边主要贴一段代码来看看这两种东西使用上的区别到底在哪. #include <stdio.h> int main(int argc, ...