题解 | 二叉树的三种遍历方式非递归版本汇总

二叉树的后序遍历

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

前序遍历

我们利用栈的特性,先将根节点压栈,每次都是从栈中弹出一个,然后将这个节点的右、左孩子压栈。

注意:压栈时,一定要先压右孩子,然后是左孩子

    public int[] preorderTraversal (TreeNode root) {
        if(root == null){
            return new int[]{};
        }
        Stack<TreeNode> st = new Stack<TreeNode>();
        List<Integer> list = new ArrayList<>();
        st.push(root);
        while(!st.isEmpty()){
            TreeNode node = st.pop();
            list.add(node.val);
		  // 先压右孩子
            if(node.right != null){
                st.push(node.right);
            }
            if(node.left != null){
                st.push(node.left);
            }
        }
        int[] res = new int[list.size()];
        
        for(int i = 0; i< list.size(); i ++){
            res[i] = list.get(i).intValue();
        }
        return res;
    }

后序遍历

后续遍历只需要在前序遍历的模版上稍作修改即可。

前序遍历 是 中左右,我们调整左右两个节点的压栈顺序,左孩子先入栈,则最终得到的顺序是中右左,然后反转这个结果就是后续遍历左右中

import java.util.*;

public class Solution {
   
    public int[] postorderTraversal (TreeNode root) {
        if(root == null){
            return new int[]{};
        }
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> st = new Stack<>();
        st.push(root);
        while(!st.isEmpty()){
            TreeNode node = st.pop();
            list.add(node.val);
            if(node.left != null){
                st.push(node.left);
            }
            if(node.right != null){
                st.push(node.right);
            }
        }
        Collections.reverse(list);
        int[] res = new int[list.size()];
        for(int i = 0; i < list.size() ; i ++){
            res[i] = list.get(i).intValue();
        }
        return res;
    }
}

中序遍历

中序遍历时,我们就不能使用前序遍历的模版了。

在前序遍历中,因为要访问的节点和要处理的节点是一致的,都是中间节点。

但是对于中序遍历来说,我们处理的元素顺序与访问的不一致,还需要借助指针来实现。

用一个指针来表示当前访问的节点,不断的将左孩子压栈,一直到底,然后右孩子压栈

    public int[] inorderTraversal (TreeNode root) {
        if(root == null){
            return new int[]{};
        }

        ArrayList<Integer> list = new ArrayList<>();
        Stack<TreeNode> st = new Stack<>();
        TreeNode curr = root;
        while(curr != null || !st.isEmpty()){
            while(curr != null){
                st.push(curr);
                curr = curr.left;
            }
            curr = st.pop();
            list.add(curr.val);
            curr = curr.right;
        }


        int[] res = new int[list.size()];
        for(int i = 0; i < list.size() ;i ++){
            res[i] = list.get(i).intValue();
        }
        return res;
    }

全部评论

相关推荐

时间线:&nbsp;1.4-1.5:&nbsp;boss&nbsp;牛客&nbsp;官网&nbsp;实习僧海投了两天,&nbsp;感觉确实没啥招人的啊,&nbsp;心里凉了一半.1.6:&nbsp;中午快手约面,&nbsp;下午字节hr飞书私聊约面,&nbsp;当时想着第一次面大厂感觉三个过一个一面就已经赢了.1.7:&nbsp;下午&nbsp;3点大厂处女面,&nbsp;哈哈面试官是重邮红岩的直接保送;&nbsp;5点快手一面,&nbsp;我说这个是我的第二次大厂面试,&nbsp;面试官问要是拿到字节和快手选择哪个,&nbsp;我说昨天看了一晚上快手百分百选快手哈哈哈.&nbsp;晚上5.30字节约二面,&nbsp;快手约二面,&nbsp;小红书约一面.1.8:&nbsp;下午2点快手二面,&nbsp;聊天面体验非常好(当天电话确认入职时间);&nbsp;4点字节二面这次不是校友了,&nbsp;然后有一个CSS实现switch效果的忘记属性咋写了,&nbsp;感觉危了;&nbsp;7.30&nbsp;问字节hr是不是挂了;&nbsp;9点开始小红书一面,&nbsp;难死我了,&nbsp;但我还是笑着面完了,&nbsp;然后卸载了小红书,&nbsp;但是过了一会会小红书hr约二面,&nbsp;遂下回来了字节约三面.1.9:&nbsp;下午2点字节三面,&nbsp;依旧聊天+算法,&nbsp;自己太菜了有一个写错了,&nbsp;面完感觉又危了;&nbsp;5点面小红书20min结束(offer审批);5.30又去问字节hr是不是挂了,&nbsp;hr小姐姐说干嘛用一个句式,&nbsp;我说手写题又又又没写出来😂,&nbsp;2min后约hr面;8.30&nbsp;快手offer总结,&nbsp;自己运气好遇到了好公司好部门好面试官,&nbsp;字节剪映&nbsp;快手电商&nbsp;小红书支付的面试体验都非常好,&nbsp;不会的题会带你一步一步思考,&nbsp;流程也非常快全部都是当天推进,&nbsp;小红书是以分钟为单位推进.&nbsp;&nbsp;面经以及细节等我慢慢整理,&nbsp;&nbsp;以及保佑所有的审批不要出问题,&nbsp;我是真怕最后全过了0offer😂bg:&nbsp;重邮&nbsp;大数据&nbsp;蓝山工作室&nbsp;一段非大厂实习
独角仙梦境:这是真👻了
找实习记录
点赞 评论 收藏
分享
LastWh1spe...:ssob真有些人和那个没睡醒一样
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务