Problem
Solution
递归版本的后序遍历十分简单,不再赘述。
仿照preorder、inorder的思路,我们要找出一种迭代模式,不断重复这种模式,就可以得到最后的后序遍历结果。
后序的访问顺序是左右中,因此最先被访问的,是从根节点出发优先往左走,若无左孩子可以向右边走(有右孩子的话)。这样一路下来,所有路过的节点都被压入栈中(如果同时有左右孩子要入栈,那么一定要右孩子先入栈,因为栈是FILO)。
当我们向上回溯时会发现,栈里作为右孩子入栈的节点,还需继续套用上述模式遍历,若不是作为右孩子入栈,那么说明可以直接访问该节点了。
因定义时节点并没有定义parent指针域,遍历时需要引入一个pre,指向上一轮的节点p,判断当前栈顶元素是不是p的父节点,如果是那么可以直接访问,不是,就说明当前节点是p节点的右兄弟,对该右子树继续套用上述这个过程即可。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void gotoHLVFL(stack<TreeNode *> &st) {
TreeNode *p;
while (p = st.top()) {
if (p->left) {
if (p->right) st.push(p->right);
st.push(p->left);
} else {
st.push(p->right);
}
}
st.pop();
// while(!st.empty())
// {
// printf("%d\n",st.top()->val);
// st.pop();
// }
return;
}
vector<int> postorderTraversal(TreeNode *root) {
stack<TreeNode *> st;
vector<int> ans;
if (root) st.push(root);
TreeNode *p = root;
TreeNode *pre = root;
while (!st.empty()) {
p = st.top();
if (p->left != pre && p->right != pre)
gotoHLVFL(st);
p = st.top();
st.pop();
ans.push_back(p->val);
// printf("%d\n", p->val);
pre = p;
}
return ans;
}
};