Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [3,2,1]
Note: Recursive solution is trivial, could you do it iteratively?
题目的大概意思是不用递归的方法去后序遍历二叉树,在这里我用了栈来保存结点,不过递归就是栈,这样看来,递归和非递归也没什么区别了,时间复杂度是以结点数量为量,即O(n),栈这个辅存耗费O(n)的空间复杂度,思想也很简单,每次取栈顶元素,若其优先加入左子树,当左空右不空时加入右子树,都为空,当前结点值就可存入vector。当完成左或者右子树的遍历时,下次应该取其父结点,所以需要记录下刚才已经遍历的子树,这里是把它置为空,反正也不作下一步的处理,避免再次访问造成死循环。详细代码如下:
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
TreeNode *q[100];//队列
char *a="1#23*";//测试用的数据,比较小
//层次建树
TreeNode* createTree(){
char ch;
int front=1,rear=0;
TreeNode* root,*s;
root=NULL;
ch=a[0];
while (ch!='*') {
s=NULL;
if(ch!='#')
s= new TreeNode(ch-'0');
rear++;
q[rear]=s;
if(rear==1)
root=s;
else{
if(s){
if(rear%2==0)
q[front]->left=s;
else
q[front]->right=s;
}
if(rear%2==1)
while (q[++front]==NULL&&front<=rear);
}//else
ch=*++a;
}//while
return root;
}
//非递归后序遍历
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if(root==NULL)
return result;
TreeNode *temp,*pre;//pre用于记录之前遍历过的子树
pre=NULL;
st.push(root);
while (!st.empty()){
temp=st.top();
if(pre!=NULL){//遍历过的子树直接置为空,如果要求不可改变原来的树,就不能这样做
if(temp->left==pre)
temp->left=NULL;
else
temp->right=NULL;
pre=NULL;
}
if(temp->left)
st.push(temp->left);
else {
if(temp->right)
st.push(temp->right);
else{
// cout<<temp->val<<" ";
result.push_back(temp->val);
pre=temp;
st.pop();
}
}
}
return result;
}
//递归后序遍历,验证非递归遍历结果
void postOrder(TreeNode *root){
if(root==NULL)
return;
else{
postOrder(root->left);
postOrder(root->right);
cout<<root->val<<" ";
}
}
//打印非递归遍历返回的vector
void printVector(vector<int> &v){
cout<<endl;
vector<int>::iterator it;
for(it=v.begin();it!=v.end();it++){
cout<<(*it)<<" ";
}
cout<<endl;
}
int main()
{
TreeNode* tree;
tree=createTree();
postOrder(tree);
printVector(postorderTraversal(tree));
return 0;
}
此法较为笨拙,后又修改了一下如下:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if(root==NULL)
return result;
TreeNode *temp,*pre;//pre用于记录之前遍历过的子树
pre=NULL;
st.push(root);
while (!st.empty()){
temp=st.top();
if((temp->left==NULL&&temp->right==NULL)||(pre!=NULL&&(temp->left==pre||temp->right==pre))){
result.push_back(temp->val);
st.pop();
pre=temp;
}
else{
if(temp->right)
st.push(temp->right);
if(temp->left)
st.push(temp->left);
}
}
return result;
}