94. 二叉树的中序遍历

给定一个二叉树的根节点 root ,返回它的 中序 遍历。

示例 1:

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

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

输入:root = [1]
输出:[1]
示例 4:

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

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

提示:
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal

    // 迭代算法需要掌握
    // 对一个节点有三次访问:第一次访问-从左孩子返回访问-从右孩子返回访问
    // 前中后顺序是指:在哪次打印值:
    // 中序遍历:遍历顺序:左-中-右

    public List<Integer> inorderTraversal(TreeNode root) {


        List<Integer> ret = new ArrayList<>();
        if(root == null) {
            return ret;
        }

        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode cur = root;
        //由于是左子树都遍历完,在打印中间节点,之后才是右子树。
        // 由于访问顺序和打印顺序不一致,所以先让后遍历的节点都入栈。
        
        while(cur != null) {
            stack.push(cur);
            cur = cur.left;
        }

        while(!stack.isEmpty()) {
            // 此时的栈顶的节点是最左侧的节点,所以已经从左孩子遍历回来了,所以可以直接打印该值了
            TreeNode node = stack.pop();
            ret.add(node.val);
            // 打印完该节点,该遍历右子树了,右子树还是同样的逻辑,先左孩子,再中间,最后右孩子。
            // 右孩子也是同样的逻辑,把后遍历的放栈。
            TreeNode right = node.right;
            while(right != null) {
                stack.push(right);
                right = right.left;
            }
        }
        return ret;
    }

由于上面的代码中有了重复的逻辑,所以可以优化:

    public List<Integer> inorderTraversal(TreeNode root) {
      
        // 创建栈,利用栈的倒序,实现最先处理最左边的节点,之后出栈,逐渐处理上一侧的节点
        Deque<TreeNode> stack = new ArrayDeque<>();

        List<Integer> ret = new ArrayList<>();

        // 尽量使用局部变量处理树结构
        TreeNode cur = root;

        while(cur != null || !stack.isEmpty()) {
            // 将该节点为起点,左孩子全部放入栈中
            
             while(cur!= null) {
                 stack.push(cur);
                 cur = cur.left;
             }
            
             cur = stack.pop();
             ret.add(cur.val);
             // 出栈,处理节点的右孩子。之后右孩子做上述同样的逻辑。
             cur = cur.right;

        }
        
        return ret;  
    }

这种思路是通过左孩子入栈,之后回溯的时候再找右孩子。其实二叉树的遍历可以应用多叉树的遍历逻辑。具体思路参考590. N 叉树的后序遍历

    public List<Integer> inorderTraversal(TreeNode root) {


        if( root == null) {
            return new ArrayList<>();
        }

        List<Integer> ret = new ArrayList<>();

        Stack<TreeNode> stack = new Stack<>();

        TreeNode cur = root;
        stack.push(cur);

        while(!stack.isEmpty()) {
            cur = stack.pop();
            if(cur != null) {

                if(cur.right != null) {
                    stack.push(cur.right);
                }
                stack.push(cur);
                stack.push(null);

                if(cur.left != null) {
                    stack.push(cur.left);
                }


            } else {
                cur = stack.pop();
                ret.add(cur.val);
            }
        }
        return ret;


    }
posted @ 2022-02-22 18:35  一颗青菜  阅读(17)  评论(0)    收藏  举报