给一个二叉树,返回后序遍历的节点值
Note:递归很容易,那么迭代呢?
方法一:递归
1.递归结束,root==NULL
2.递归root->left
3.递归root->right
4.存root->val
Status: Accepted
Runtime: 0 ms
class Solution {
public:
void fillres(TreeNode* root, vector<int> &result){
if(root == NULL) return;
fillres(root->left, result);
fillres(root->right, result);
result.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
fillres(root, result);
return result;
}
};
方法二:迭代
后序遍历:左右中
栈:压中,压右,压左,出左,出右,出中
出栈:a.左右孩子全为空,存pNode的值并出栈;b.左右孩子全出栈(上一次出栈的是当前栈顶节点pNode的左或右孩子,则pNode的孩子全出栈),存pNode的值并出栈。
不出栈:a.左右孩子不全为空,继续压孩子;b.左右孩子未压栈(若上一次出栈的不是当前栈顶节点pNode的左或右孩子,则pNode的孩子还未压栈),继续压孩子。
1.创建一个vector存后序遍历节点值
2.创建一个stack模拟递归
3.创建两个节点指针,一个指向当前栈顶节点pNode,另一个指向上一次while循环的栈顶节点preNode(两种情况:a.preNode为刚才压入栈的节点,压栈过程,无用;b.preNode为刚从栈顶pop出的节点,出栈过程,有用,见5、6)
4.while循环,判断stack非空
5.压栈过程:若上一次while循环的栈顶节点(preNode)不是当前栈顶节点(pNode)的孩子节点(而是父节点或左兄弟节点),则当前栈顶节点(pNode)的孩子还未压栈(未被遍历),故不pop,继续压。
6.出栈过程:若上一次while循环的栈顶节点(preNode)是当前栈顶节点(pNode)的(左或右)孩子节点,则当前栈顶节点(pNode)的孩子已全部出栈(被遍历过),故pop当前栈顶节点pNode。
7.返回vector
Status: Accepted
Runtime: 0 ms
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
if(root == NULL) return result;
TreeNode* pNode = root, *preNode = root;
stack<TreeNode*> stk;
stk.push(root);
while(!stk.empty()){
pNode = stk.top();
if(preNode != pNode->left&& preNode != pNode->right){
if(pNode->right){
stk.push(pNode->right);
}
if(pNode->left){
stk.push(pNode->left);
}
}
if(pNode->left == NULL && pNode->right == NULL || preNode == pNode->left || preNode == pNode->right){
result.push_back(pNode->val);
stk.pop();
}
preNode = pNode;
}
return result;
}
};