题目描述
分析
后序遍历即先访问左子树和右子树,再访问根节点。递归写法很简单,但题目要求用非递归写法。不是太容易写,面试时候说不定会问(感觉啥都会问emmm),代码如下,已注释关键部分,可以在理解的基础上加以记忆。
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res; //存放结果
// 先找到最“左下”的那个节点,该节点一定没有左子树(右子树不一定)。
// 同时将“沿途”所有经过的节点入栈
stack<TreeNode*> s;
TreeNode* cur = root; //当前节点
TreeNode* pre = NULL; //前一个被访问的节点,初始为空
while (cur) {
s.push(cur);
cur = cur->left;
}
// 从栈顶元素开始
while (!s.empty()) {
cur = s.top(); //出栈一个节点,作为当前节点
s.pop();
/*当前节点被访问的条件是:要么其右孩子为空,要么其右子树恰好在上一次被访问。
至于其左孩子,其实不用单独考虑,因为它要么为空,要么就是肯定已经被访问过了*/
if (cur->right == NULL || cur->right == pre) { // 如果cur的右孩子为空,或者恰好在上一轮被访问,则当前节点应该被访问
res.push_back(cur->val);
pre = cur;
}
else { //否则(也就是cur的右孩子不为空,且没有被访问),就先后续遍历右子树(也要先找到“右下角”节点,并将沿途节点入栈)
s.push(cur); //当前节点再压会栈中,等右孩子访问完毕才会再出栈访问
cur = cur->right;
while (cur) {
s.push(cur);
cur = cur->left;
}
}
}
return res;
}
};