LeetCode94. Binary Tree Inorder Traversal
题目
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [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的更多相关文章
- (二叉树 递归) leetcode94. Binary Tree Inorder Traversal
Given a binary tree, return the inorder traversal of its nodes' values. Example: Input: [1,null,2,3] ...
- LeetCode94 Binary Tree Inorder Traversal(迭代实现) Java
题目: Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binar ...
- Leetcode94. Binary Tree Inorder Traversal二叉树的中序遍历(两种算法)
给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 递归: class So ...
- LeetCode 94. 二叉树的中序遍历(Binary Tree Inorder Traversal)
94. 二叉树的中序遍历 94. Binary Tree Inorder Traversal 题目描述 给定一个二叉树,返回它的 中序 遍历. LeetCode94. Binary Tree Inor ...
- LintCode Binary Tree Inorder Traversal
Binary Tree Inorder Traversal Given a binary tree, return the inorder traversal of its nodes' values ...
- 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 ...
- 3月3日(4) Binary Tree Inorder Traversal
原题: Binary Tree Inorder Traversal 和 3月3日(2) Binary Tree Preorder Traversal 类似,只不过变成中序遍历,把前序遍历的代码拿出来, ...
- 49. leetcode 94. Binary Tree Inorder Traversal
94. Binary Tree Inorder Traversal 二叉树的中序遍历 递归方法: 非递归:要借助栈,可以利用C++的stack
- LeetCode: Binary Tree Inorder Traversal 解题报告
Binary Tree Inorder Traversal Given a binary tree, return the inorder traversal of its nodes' values ...
随机推荐
- 硬盘和显卡的访问与控制(一)——《x86汇编语言:从实模式到保护模式》读书笔记01
本文是<x86汇编语言:从实模式到保护模式>(电子工业出版社)的读书实验笔记. 这篇文章我们先不分析代码,而是说一下在Bochs环境下如何看到实验结果. 需要的源码文件 第一个文件是加载程 ...
- pat06-图7. How Long Does It Take (25)
06-图7. How Long Does It Take (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue ...
- SSH密钥登录原理
Client 发送请求 login 请求 --> Server 接受请求 --> 根据 authorized_key 文件中的对应 Client 的 ip 地址的公钥对一串随机数进行加密 ...
- HDU 5375——Gray code——————【dp||讨论】
Gray code Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- 在基于WCF开发的Web Service导出WSDL定义问题及自定义wsdl:port 名称
在契约优先的Web服务开发过程中,往往是先拿到WSDL服务定义,各家开发各自的服务实现或客户端,然后互相调用. 尽管Web Service的标准已经发布很多年,但各 ...
- 修改默认 JVM 参数 securerandom.source
最近在云服务器上部署tomcat的时候,执行 startup.sh老是卡住了. 开始以为是日志配的不对,因为在对象中引入的是slf4,不是apache的log4j,后面把所有引入的地方都修改为Apac ...
- CSS命名规范(规则)
常用的CSS命名规则 头:header内容:content/container尾:footer导航:nav侧栏:sidebar栏目:column页面外围控制整体佈局宽度:wrapper左右中:left ...
- 零基础逆向工程36_Win32_10_互斥体_互斥体与临界区的区别
1 引言 讲了第二个内核对象,互斥体.前面已经学过一个内核对象,线程.这节讲两个函数,WaitForSingleObject()和WaitForMultipleObjects().因此这两个函数是根据 ...
- SpringBoot支持Xml数据格式显示
第一步:pom文件添加依赖 <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> < ...
- 花3分钟了解下C/C++中的函数可变参简单实现
1.可变参函数的原理 C/C++函数的参数是存放在栈区的,并且参数的入栈是从参数的右边开始,即最后一个参数先入栈,而第一个参数最后才入栈,所以,根据栈的后进先出性质,函数总能找到第一个参数.所以,可变 ...