145. Binary Tree Postorder Traversal

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;
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值