【刷题打卡】145. 二叉树的后序遍历

72 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

一、题目描述:

145. 二叉树的后序遍历 - 力扣(LeetCode) (leetcode-cn.com)

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历

示例 1:

image.png

输入:root = [1,null,2,3]
输出:[3,2,1]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

提示:

  • 树中节点的数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

二、思路分析:

二叉树的后续遍历时最难的一种遍历方式,因为无法判定是否遍历过右子树,所以无法判断是否访问当前节点(只有访问过右子树后才能访问父节点)。

问题:

如何确定当前状态是访问了左子树后过来,还是访问了右子树后来的?

如果是访问左子树后过来,那么要访问右子树,如果是访问右子树后过来,那么访问当前节点。

我们可以根据这一特性来甄别:

划重点:

如果是访问的右子树过来,那么上次访问结果是当前的右子树,通过纪录上个访问的节点,即可解决该问题。

还有一种方法是黑白标记法,右节点标记为白,左节点标记为黑。

三、AC 代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        
        vector<int> result;
        stack<TreeNode*> s;
        
        TreeNode *pre_visit = nullptr;            //记住上次访问
        while(root||s.size()){
            while(root){
                s.emplace(root);
                root = root->left;
            }
            root = s.top();
            s.pop();
            if((root->right==nullptr)||(root->right == pre_visit)){
                pre_visit = root;
                result.push_back(root->val);
                root = nullptr;
            }
            else{
                s.emplace(root);
                root = root->right;
            }
        }
        return result;
    }
};

范文参考

我是笨蛋,分享一个偷懒背题的思路。后续遍历 与前序遍历的一点点差别 - 二叉树的后序遍历 - 力扣(LeetCode)

【专题讲解】 二叉树前中后序遍历 代码简洁易懂 - 二叉树的后序遍历 - 力扣(LeetCode)