相似题目:
二叉树的前序遍历:http://blog.youkuaiyun.com/Arcome/article/details/53672912
二叉树的中序遍历:http://blog.youkuaiyun.com/arcome/article/details/53672748
二叉树的后序遍历:http://blog.youkuaiyun.com/Arcome/article/details/53740883
Problem
Given a binary tree, return the preorder traversal of its nodes' values.
Note:
Recursive solution is trivial, could you do it iteratively?
Example
Given binary tree {1,#,2,3},
1
\
2
/
3
return [1,2,3].
Algorithm
整理一下题意:给定一棵二叉树,要求返回其前序遍历结果。
首先是熟悉的递归版前序遍历的方法。将访问节点的操作设置在左节点的递归和右节点的递归之前。
代码如下。
//递归版本,用时0ms
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
if(root==NULL) return result;
preorder(result,root);
return result;
}
void preorder(vector<int>& result, TreeNode*root){
result.push_back(root->val);
if(root->left!=NULL) preorder(result,root->left);
if(root->right!=NULL) preorder(result,root->right);
}
};
对于非递归的实现,需要使用栈。
有两种方法,第一种方法与层次遍历比较相似。不过层次遍历使用的是队列,而前序遍历使用的是栈。
由于前序遍历总是把父节点排在前面子节点前面,所以每次压入子节点前先访问父节点。注意前序遍历中,左子在右子前面,所以应先把右子压栈,再把左子压栈。
代码如下。
//非递归版本1,用时0ms
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
if(root==NULL) return result;
stack<TreeNode*> st;
TreeNode*p=root;
st.push(p);
while(!st.empty()){
p=st.top();
st.pop();
result.push_back(p->val);
if(p->right!=NULL) st.push(p->right);
if(p->left!=NULL) st.push(p->left);
}
return result;
}
};
第二种非递归方法的框架与中序遍历的迭代解法类似。
不断将左节点压入栈中,直到左节点为NULL。然后对指针指向的根节点操作,若节点为空,则设置指正指向栈顶的节点的右子,然后弹出栈顶。
因为某个节点作为父节点时必然也是作为其父节点的子节点,所以这一方法可以遍历所有节点。此方法十分巧妙,需要熟记。
代码如下。
//非递归版本2,用时3ms
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> path;
if(root==NULL) return path;
stack<TreeNode*> st;
TreeNode*p=root;
while(p!=NULL||!st.empty()){
while(p!=NULL){
path.push_back(p->val);
st.push(p);
p=p->left;
}
if(p==NULL){
p=st.top()->right;
st.pop();
}
}
return path;
}
};