LeetCode 145 二叉树的后序遍历(重要)

这篇博客介绍了如何使用栈来非递归地实现二叉树的后序遍历。通过实例化两个栈,一个存储节点,另一个存储节点的状态码,实现了类似递归的功能。在遍历过程中,根据状态码的不同执行相应的操作,如压入左右子节点或输出当前节点。这种方法避免了递归调用带来的开销,对于理解栈的应用和二叉树遍历提供了新的视角。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

给定一个二叉树,返回它的 后序 遍历。
在这里插入图片描述

解题思路

本题我们不使用递归的方式,而是使用栈的方式来实现,这个技巧是一个模拟系统递归的过程,往后可以使用该技巧实现几乎所有的递归函数转非递归函数

实例化两个栈,s1存储树节点,s2存储树节点的状态码,状态码共有3个值0,1,2;0代表该节点需要压入左节点,1代表该节点需要压入右节点,2代表左右子树都遍历完了,输出本节点。

代码

public List<Integer> postorderTraversal(TreeNode root) {
        if(root == null){
            return new ArrayList<Integer>();
        }
        //规定状态码为0时,需要压入左节点
        //状态码为1时,需要压入右节点
        //状态码为2时,表示无左右节点或者左右节点已遍历完,轮到该节点输出了,需要弹栈了
        Stack<TreeNode> s1  = new Stack<TreeNode>();//栈1,用来存储具体的节点
        Stack<Integer> s2  = new Stack<Integer>();//栈2,用来存储对应节点的状态码
        List<Integer> list = new ArrayList<Integer>();//存储结果的数组
        //初始化
        s1.push(root);//根节点入栈
        s2.push(0);//状态码0
        while(!s1.empty()) {
            switch (s2.peek()) {
                case 0:
                    //如果左节点为空
                    if(s1.peek().left == null) {
                        s2.pop();
                        s2.push(1);//更新状态码
                        break;
                    }
                    //栈压入左节点
                    s1.push(s1.peek().left);
                    s2.pop();
                    s2.push(1);//更新状态码
                    s2.push(0);//为压入的左节点添置对应的状态码
                    break;
                case 1:
                    if(s1.peek().right == null) {
                        s2.pop();
                        s2.push(2);
                        break;
                    }
                    //压入右子树
                    s1.push(s1.peek().right);
                    s2.pop();
                    s2.push(2);
                    s2.push(0);
                    break;
                case 2:
                    list.add(s1.peek().val);
                    s1.pop();
                    s2.pop();
                    break;
            }
        }
        return list;
    }

总结

  1. 栈的应用场景非常广,就本题来看收获到的就是利用双栈来存储一个对象的地址和其对应的状态,不同的状态做不同的事,这是一种很实用的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值