一、节点定义
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
二、递归写法
记录一下用于返回的vector的定义位置
class Solution {
public:
vector<int> value;
//一定要定义成全局变量,
//否则后面返回的只是函数体里最后一个递归函数定义的value,
//那只是整个value的一部分
vector<int> postorderTraversal(TreeNode *root) {
if(!root){
return value;
}
value = postorderTraversal(root->left);//左
value = postorderTraversal(root->right);//右
value.push_back(root->val);//本身节点访问
return value;
}
void print(vector<int> value){
vector<int>::iterator it;
for(it=value.begin();it!=value.end();it++)
cout<<*it<<",";
cout<<endl;
}
};
三、非递归写法
class Solution {
public:
vector<int> value;
vector<int> postorderTraversal(TreeNode *root) {
if(!root){
return value;
}
stack<TreeNode *> sta;
TreeNode *r = root;//当前被操作的节点
TreeNode *pre = root;//记录刚被访问过的节点
while( r || !sta.empty() ){
//沿着左子树找到最左节点,边找边依次入栈
while(r){
sta.push(r);
r = r->left;
}
while( !sta.empty() ){
r = sta.top();
//存在右结点且没被访问
if(r->right && pre != r->right){
r = r->right;//转到右子树
//在右子树上找到最左节点,并依次入栈
while(r){
sta.push(r);
r = r->left;
}
}else{//不存在右结点或者右结点已经被访问了,即可将当前节点弹栈并访问
sta.pop();
value.push_back(r->val);
pre = r;//更新刚被访问过的节点
}
}
//之前的while循环已经把所有节点都遍历了,
//这里不置空的话就跳不出最外层循环
r = NULL;
}
return value;
}
四、验证
int main() {
TreeNode *a = new TreeNode(1);
TreeNode *b = new TreeNode(2);
TreeNode *c = new TreeNode(3);
a->right = b;
b->left = c;
Solution slt;
vector<int> value;
value = slt.postorderTraversal(a);
slt.print(value);
return 0;
}