题目

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

示例:

输入: [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. Cloudera Manager卸载笔记

    1.通过管理平台分别停止组件服务和Cloudera Management Service 2.通过管理平台注销并移除Parcles (在控制台注销并移除,无论是安装的Parcles还是未安装的Parc ...

  2. 【LDAP】LDAP 中 CN, OU, DC 的含义

    1. LDAP的存储规则 区分名(DN,Distinguished Name) 和自然界中的树不同,文件系统/LDAP/电话号码簿目录的每一片枝叶都至少有一个独一无二的属性,这一属性可以帮助我们来区别 ...

  3. 异步请求返回json对象

    后台mvc: var result = new { flag = ture, eMail = "949096562@qq.com"}; if (result.flag) { ret ...

  4. 7.vs的基本设置

    1.运行代码的两种方式 (1) 按F5 (2)点击快速菜单栏上面的绿色三角形按钮. 2.生成解决方案 F6. 3.在代码上看见红色的波浪线,表示代码有语法错误. 4.一般我们在运行一个程序之前,我们先 ...

  5. 缩小javascript文件大小之缩编、混淆

    写前端的相信都遇到过要提高网页的性能,其中javascript文件越小,浏览器的下载速度面对文件的读取和解析就更快.而一般我们在开发又需要一定的代码规范来使我们的代码更加的容易维护和读懂,但是大量空格 ...

  6. JQ单双引号转义

    var temp = "${row.address_province}"; alert(temp);——————即变量temp alert("\'"+temp+ ...

  7. Web前端开发规范(一)

    1.前言 网页开发技术从1989年开始至今已经走过了20余年,从最初纯粹的学术交流,到门户网站.电子商务网站.博客.E-mail.Web游戏.SNS网站等,以及到如今的移动Web网站(其实可以认为是P ...

  8. Azure 1 月新公布

    Azure 1 月新发布:Microsoft Power BI Embedded 公共预览和计算机视觉 API 标准版的更新以及 Azure IoT 网关 SDK 和中心设备管理新功能正式发布以及关于 ...

  9. word中已删除设置是否显示

        我们打开别人发过来的文档时经常会出现如下图所示,其实这个不是文档的异常,只是word设置显示了修订版标记,如果我们需要去除这个,只需要在审阅-修订功能下面选择显示最终版即可(测试用的10版,其 ...

  10. centos 7中磁盘挂载重启后挂载失效

     在centos 7磁盘挂载成功后,关机重启,挂载磁盘失效,需要重新挂载,不用重新挂载的开机挂载方法如下: 1.先检验要挂载的磁盘是否已被挂载,有的话先卸除 2.修改 /etc/fstab 文件 ,最 ...