94. Binary Tree Inorder Traversal
2016-05-30 16:04
344 查看
题目:
Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree
return
Note: Recursive solution is trivial, could you do it iteratively?
confused what
read more on how binary tree is serialized on OJ.
OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
The above binary tree is serialized as
题意:
给定一个二叉树,返回节点值的中序遍历。
思路:转载地址:https://leetcode.com/discuss/36713/solutions-iterative-recursive-traversal-different-solutions
思路一:
基于堆栈实现中序遍历。
代码:2ms
C++版:0ms
/**
* 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> result;
stack<TreeNode*> inStack;
TreeNode* curNode = root;
while(curNode || !inStack.empty()){
if(curNode){
inStack.push(curNode);
curNode = curNode->left;
}else{
curNode = inStack.top();
inStack.pop();
result.push_back(curNode->val);
curNode = curNode->right;
}
}
return result;
}
};
思路二:
采用递归调用的方式实现中序遍历,逻辑简单。使用空间换时间。
代码:0ms
/**
* 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> result;
inorderTraversal(root, result);
return result;
}
void inorderTraversal(TreeNode* root, vector<int>& result){
if(!root){
return;
}
inorderTraversal(root->left, result);
result.push_back(root->val);
inorderTraversal(root->right, result);
}
};
思路三:转载地址:http://blog.csdn.net/mxw976235955/article/details/39829973
使用Morris算法来遍历二叉树。其时间复杂度仍然是O(n),但是空间复杂度却只有O(1)。
其优点概括来说有两个:
1. O(1)空间复杂度,即只能使用常数空间;
2. 二叉树的形状不会被破坏(中间过程允许改变其形状)。
要使用O(1)空间进行遍历,最大的难点在于,遍历到子节点的时候怎样重新返回到父节点(假设节点中没有指向父节点的p指针),由于不能用栈作为辅助空间。为了解决这个问题,Morris方法用到了线索二叉树(threaded binary tree)的概念。在Morris方法中不需要为每个节点额外分配指针指向其前驱(predecessor)和后继节点(successor),只需要利用叶子节点中的左右空指针指向某种顺序遍历下的前驱节点或后继节点就可以了。
它使用二叉树中的叶节点的right指针来保存后面将要访问的节点的信息,当这个right指针使用完成之后,再将它置为NULL,但是在访问过程中有些节点会访问两次,所以与递归的空间换时间的思路不同,Morris则是使用时间换空间的思想。
代码:0ms
/**
* 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> result;
TreeNode* curNode = root;
while(curNode){
if(curNode->left){
TreeNode* prev = curNode->left;
while(prev->right && prev->right!=curNode){
prev = prev->right;
}
if(!(prev->right)){
prev->right = curNode;
curNode = curNode->left;
}else{
prev->right = NULL;
result.push_back(curNode->val);
curNode = curNode->right;
}
}else{
result.push_back(curNode->val);
curNode = curNode->right;
}
}
return result;
}
};
Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree
{1,#,2,3},
1 \ 2 / 3
return
[1,3,2].
Note: Recursive solution is trivial, could you do it iteratively?
confused what
"{1,#,2,3}"means? >
read more on how binary tree is serialized on OJ.
OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
1 / \ 2 3 / 4 \ 5
The above binary tree is serialized as
"{1,2,3,#,#,4,#,#,5}".
题意:
给定一个二叉树,返回节点值的中序遍历。
思路:转载地址:https://leetcode.com/discuss/36713/solutions-iterative-recursive-traversal-different-solutions
思路一:
基于堆栈实现中序遍历。
代码:2ms
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> list = new ArrayList<Integer>(); Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode cur = root; while(cur!=null || !stack.empty()){ while(cur!=null){ stack.add(cur); cur = cur.left; } cur = stack.pop(); list.add(cur.val); cur = cur.right; } return list; } }
C++版:0ms
/**
* 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> result;
stack<TreeNode*> inStack;
TreeNode* curNode = root;
while(curNode || !inStack.empty()){
if(curNode){
inStack.push(curNode);
curNode = curNode->left;
}else{
curNode = inStack.top();
inStack.pop();
result.push_back(curNode->val);
curNode = curNode->right;
}
}
return result;
}
};
思路二:
采用递归调用的方式实现中序遍历,逻辑简单。使用空间换时间。
代码:0ms
/**
* 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> result;
inorderTraversal(root, result);
return result;
}
void inorderTraversal(TreeNode* root, vector<int>& result){
if(!root){
return;
}
inorderTraversal(root->left, result);
result.push_back(root->val);
inorderTraversal(root->right, result);
}
};
思路三:转载地址:http://blog.csdn.net/mxw976235955/article/details/39829973
使用Morris算法来遍历二叉树。其时间复杂度仍然是O(n),但是空间复杂度却只有O(1)。
其优点概括来说有两个:
1. O(1)空间复杂度,即只能使用常数空间;
2. 二叉树的形状不会被破坏(中间过程允许改变其形状)。
要使用O(1)空间进行遍历,最大的难点在于,遍历到子节点的时候怎样重新返回到父节点(假设节点中没有指向父节点的p指针),由于不能用栈作为辅助空间。为了解决这个问题,Morris方法用到了线索二叉树(threaded binary tree)的概念。在Morris方法中不需要为每个节点额外分配指针指向其前驱(predecessor)和后继节点(successor),只需要利用叶子节点中的左右空指针指向某种顺序遍历下的前驱节点或后继节点就可以了。
它使用二叉树中的叶节点的right指针来保存后面将要访问的节点的信息,当这个right指针使用完成之后,再将它置为NULL,但是在访问过程中有些节点会访问两次,所以与递归的空间换时间的思路不同,Morris则是使用时间换空间的思想。
代码:0ms
/**
* 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> result;
TreeNode* curNode = root;
while(curNode){
if(curNode->left){
TreeNode* prev = curNode->left;
while(prev->right && prev->right!=curNode){
prev = prev->right;
}
if(!(prev->right)){
prev->right = curNode;
curNode = curNode->left;
}else{
prev->right = NULL;
result.push_back(curNode->val);
curNode = curNode->right;
}
}else{
result.push_back(curNode->val);
curNode = curNode->right;
}
}
return result;
}
};
相关文章推荐
- 算法6— 判断两个链表是否相交
- vector map删除元素
- CSS背景图拉伸自适应尺寸,全浏览器兼容
- 【android】:android颜色表
- ThinkPHP(1)——创建ThinkPHP项目
- MVC返回JSON数据格式书写方式
- linux脚本:ftp自动传输文件
- input 正则控制输入
- springmvc默认首页问题
- Struts2源码分析
- 杨绛与钱钟书,人世间最理想的婚姻
- SurfaceView
- 数据结构实验之队列一:排队买饭
- Java8新特性(三)------Stream
- Yii框架记录
- 基础知识系列☞DataReader和DataSet区别
- linux find命令
- 2016年 团体程序设计天梯赛 - 模拟赛
- Attention And Memory in Deep Learning And NLP
- JSPatch技术文档