001 递归
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int>res;
helper(root,res);
return res;
}
void helper(TreeNode * root, vector<int>&res){
if(!root) return;
helper(root->left,res);
helper(root->right,res);
res.push_back(root->val);
}
};
002 栈
vector<int> postorderTraversal(TreeNode* root){
vector<int>ans;
TreeNode* pre = nullptr;
//pre 在后续遍历的前面的一个结点
stack<TreeNode *> s;
//如果栈中还有元素 或者当前结点root 非空
while (!s.empty() || root) {
//顺着左子树走并且将所有元素压入栈中
while (root) {
s.push(root);
root = root->left;
}
/*
当没有任何元素可以压栈的时候
就拿栈顶元素,注意这里并不将栈顶元素弹出
因为在迭代时,根结点 需要遍历两次,这里需要判断一下,
如果是第一次遍历是不能弹栈的
*/
root = s.top();
/*
1.如果当前结点右子树为空,那么右子树没有遍历的必要
需要将当前结点放在ans中;
2.将root。right==pre时,那么右子树已经被打印过了那么此时需要将当前结点放到ans中
*/
if (!root->right || root->right == pre) {
//如果此时叠词遍历是根结点,所以放到ans中
ans.push_back(root->val);
printf("pre value===%d \n",pre->val);
//因为已经为第二次遍历根结点,所以需要更新pre
s.pop();
/*
已经打印完毕,需要设置空,否则下一轮循环还会遍历root的左子树
*/
pre = root;
printf("pre value===%d \n",pre->val);
root = nullptr;
}else{
/*
第一次走到root 不能放ans中,因为root的右子树还么有遍历
需要将root的结点的右子树遍历
*/
root = root->right;
}
}
return ans;
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode *>stk;
while(!stk.empty() || root){
while(root){
res.push_back(root->val);
stk.push(root);
root = root->right;
}
TreeNode *cur = stk.top();
stk.pop();
root = cur->left;
}
reverse(res.begin(),res.end());
return res;
}