题解 | #二叉树的后序遍历#

二叉树的后序遍历

https://www.nowcoder.com/practice/1291064f4d5d4bdeaefbf0dd47d78541

/**
 * struct TreeNode {
 *  int val;
 *  struct TreeNode *left;
 *  struct TreeNode *right;
 *  TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
#include <stack>
#include <vector>
class Solution {
  public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @return int整型vector
     */
    vector<int> postorderTraversal(TreeNode* root) {
        // write code here
        stack<TreeNode*> Node;
        vector<int> order;
        while (root != nullptr || !Node.empty()) {
            while (root != nullptr) {
                Node.push(root);
                if(root->left!=nullptr)
                    root = root->left;
                else
                    root = root->right;
            }
            root = Node.top();
            Node.pop();
            order.push_back(root->val);
            if (!Node.empty()&&Node.top()->right != nullptr && Node.top()->left == root)
                root = Node.top()->right;
            else
                root = nullptr;
            }
            return order;
        }
};

后序遍历的非递归真的好难啊呜呜呜呜呜,看了三遍模板才写出来。

整个思路就是,如果当前节点非空,就放入栈,然后看看左边能不能往下,如果左边到头了就往右边,直到当前节点为空,也就是右边也到头了。这个时候栈里面存的就是最左边结点的右节点,也就是此时需要输出的位置(这里要注意,后序是左右根,对于最左结点来说,自己是根,如果他自己还有右节点,那需要先输出他的右结点,再输出他自己)。

将该节点从栈中弹出,作为新的root。

后面是一个比较绕的逻辑,我们现在面临的一个问题是,从当前这个弹出的root结点已经处理完了,下面回到此时的栈顶的节点,但是现在回到这个栈顶结点,是因为左边遍历完了回来的,还是因为右边遍历完了回来的,这两者的区别在于处理完当前的root,是找栈顶结点的右子树,还是root自己就是栈顶结点右子树,结束了需要直接处理此时的栈顶结点?

如果是第一种情况,也就是root是栈顶结点的左子树,那么将root赋值为Node.top()->right.如果是第二种情况,直接将root置为空,即可进入下次循环,回到上面直接处理栈顶结点的逻辑(打印栈顶结点值,将栈顶pop)

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务