题目:
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 \ 5The above binary tree is serialized as
"{1,2,3,#,#,4,#,#,5}"
.
/** * 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; } };