数据结构-145. 二叉树的后序遍历

124 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述:

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

 

示例 1:

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

输入:root = [] 输出:[] 示例 3:

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

提示:

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

进阶:递归算法很简单,你可以通过迭代算法完成吗?

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/bi… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

父节点在栈内会被访问两次,第一次从左子树出栈后访问父节点时,父节点不进行出栈,而是将右子树入栈,继续访问右子树。只有当右子树出栈后访问父节点时,父节点才会出栈。 所以要记录上一个出栈的节点,用来判断一个节点的右子树是否被访问过。具体思路如下

  • 找到最左下方节点并将路径上的节点入栈直到node.left为空
  • 判断栈顶(最左下方节点)node.right是否为空,不为空则以node.right为起始节点继续【1】的操作
  • 如果没有右节点/右节点已被访问过,则弹出栈顶元素,并记录当前弹出的节点

三、AC 代码:


class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
 
        List<Integer> result = new ArrayList<>();
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode curNode = root; // 标志当前节点(当节点进行入栈时不为空,节点为空时标志该出栈)
        TreeNode lastPopNode = null;// 记录上一个出栈的node
        while (!stack.isEmpty() || curNode != null) {
            if (curNode != null) {
                // 延左子树向下寻找【1】
                stack.push(curNode);
                curNode = curNode.left;
            } else {
                // curNode == null 表示左子树遍历到头/正在出栈
                curNode = stack.peek(); // 先不弹出,可能是第一次访问
                if (curNode.right == null || curNode.right == lastPopNode) {
                    // 没有右子树/右子树已访问过【3】
                    stack.pop(); // 可以弹出
                    lastPopNode = curNode;
                    result.add(curNode.val);
                    curNode = null; // 注意要把curNode置空
                } else {
                    // 有右子树且右子树未被访问过【2】
                    curNode = curNode.right; // 进入右子树
                }
            }
        }
        return result;
    }

    
}

四、总结:

image.png 三种遍历算法都做了一遍了,下面总结一下前中后序遍历顺序,如下:

前序遍历:中左右 中序遍历:左中右 后序遍历:左右中

掘友们,解题不易,留下个赞或评论再走吧!谢啦~ 💐