参考链接:
参考1:在写非递归时遇到一点困难,一直没想明白应该怎么写,最后参加这个代码终于写出来的。
http://www.cnblogs.com/changchengxiao/p/3416402.html
谢谢分享!
参考2:这个方法很有意思,利用堆栈很按后序的逆序输入再做一次逆序,赞!!!
http://www.cnblogs.com/xinsheng/p/3460480.html
题目描述
[LeetCode] 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?
题目分析
递归方法:
这个方法简单,只要按照
左儿子 -> 右儿子 -> 自己
的顺序就可以了
非递归方法1:
相比于前序遍历,后续遍历思维上难度要大些,前序遍历是通过一个stack,首先压入父亲结点,然后弹出父亲结点,并输出它的value,之后压人其右儿子,左儿子即可。然而后序遍历结点的访问顺序是:左儿子 -> 右儿子 -> 自己。那么一个结点需要两种情况下才能够输出:第一,它已经是叶子结点;第二,它不是叶子结点,但是它的儿子已经输出过(代码里非递归方法head就是用来记录访问过的儿子的)。那么基于此我们只需要记录一下当前输出的结点即可。对于一个新的结点,如果它不是叶子结点,儿子也没有访问,那么就需要将它的右儿子,左儿子压入。如果它满足输出条件,则输出它,并记录下当前输出结点。输出在stack为空时结束。
非递归方法2:
利用堆栈很按后序的逆序输入再做一次逆序
从一开始,就按 自己->右儿子->左儿子顺序输出,最后做一下逆序就好
总结
在写代码时有一个地方出了bug,有的是就是没搞明白怎么把两个vector拼在一起
这里对vector的使用方法要得当,把两个vector拼在一起的方法:
把out1,out2,拼成(out1,out2)
out2.insert(out2.begin(),out1.begin(),out1.end());//out1,out2顺序不要弄错
示例代码
/*
编译环境CFree 5.0
*/
#include
#include
#include
using namespace std;
#define METHOD 1 //1- 递归法
//#define METHOD 2//2- 堆栈方法1
//#define METHOD 3//3- 堆栈方法3
/**
* Definition for binary tree
*/
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
void printVector(vector
in,char* name)
{
printf("%s size=%d\n",name,in.size());
for(int i = 0;i< in.size();i++)
{
printf("%d ",in[i]);
}
printf("\n");
}
#if METHOD == 1
/*
这里对vector的使用方法要得当,把两个vector拼在一起的方法是
把out1,out2,拼成(out1,out2)
out2.insert(out2.begin(),out1.begin(),out1.end());//out1,out2顺序不要弄错
*/
class Solution {
public:
vector
postorderTraversal(TreeNode *root) {
vector
out; if(root == NULL) return out; vector
out1 = postorderTraversal(root->left); vector
out2 = postorderTraversal(root->right); out.insert(out.begin(),root->val); //中 out.insert(out.begin(),out2.begin(),out2.end()); //右 out.insert(out.begin(),out1.begin(),out1.end()); //左 return out; } }; #elif METHOD == 2 //堆栈方法 //这个方法不太好理解,需要加以研究 class Solution { public: vector
postorderTraversal(TreeNode *root) { vector
out; if(root == NULL) return out; TreeNode *head = root; //就是记录上一个弹出的结点 treenodeStack.push(root); while(!treenodeStack.empty()) { TreeNode *cur = treenodeStack.top();//增加一个记录点 if(cur->left == head || cur->right== head ||(cur->left == NULL && cur->right == NULL))//这个条件很关键 { treenodeStack.pop(); out.push_back(cur->val); head = cur; //printf("pop = %d\n",cur->val); //system("pause"); } else { if(cur->right != NULL) treenodeStack.push(cur->right)/*,printf("lpush = %d\n",cur->right->val)*/; if(cur->left != NULL) treenodeStack.push(cur->left)/*,printf("rpush = %d\n",cur->left->val)*/; } } return out; } private: stack
treenodeStack; }; #elif METHOD == 3 /* 这个方法赞呀!自己->右儿子->左儿子顺序输出,最后做一下逆序就好 */ class Solution { public: vector
postorderTraversal(TreeNode *root) { vector
res; if(root == NULL) return res; vector
stc; stc.push_back(root); while(!stc.empty()) { TreeNode* node = stc.back(); res.push_back(node->val); stc.pop_back(); if(node->left != NULL) { stc.push_back(node->left); } if(node->right != NULL) { stc.push_back(node->right); } } reverse(res.begin(), res.end()); return res; } }; #endif /*功能测试*/ void test0() { /* 1 2 3 4 5 6 7 */ TreeNode node1(1); TreeNode node2(2); TreeNode node3(3); TreeNode node4(4); TreeNode node5(5); TreeNode node6(6); TreeNode node7(7); node1.left = &node2; node1.right = &node3; node2.left = &node4; node2.right = &node5; node3.left = &node6; node3.right = &node7; Solution so; vector
out = so.postorderTraversal(&node1); int tmp[7] = {4,5,2,6,7,3,1}; int i = 0; for(i = 0;i<7 && i
推荐学习C++的资料
C++标准函数库
在线C++API查询