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;
}
这篇博客介绍了两种不同的方法来实现二叉树的后序遍历:一种是使用递归,另一种是利用栈。递归方法直接从根节点开始,先遍历左子树,然后遍历右子树,最后将根节点的值添加到结果中。而栈的方法则是先将所有左子节点压入栈中,然后在满足特定条件时处理右子节点和根节点。这两种方法都有效地解决了后序遍历的问题。
17万+

被折叠的 条评论
为什么被折叠?



