树 - 32.从上到下打印二叉树 - 之字形打印

在这里插入图片描述
思路,首先把根节点存储,这是树的第 0 层。
第二层,由于要从右向左打印,而在第一层保存数据的时候,我们就需要把当前的节点的右孩子放入队列,左孩子后放入队列。
第二次,由于要从左向右打印,所以,我们必须先获取第一层的左节点的左节点。所以在第二层我们就不能使用队列了,而是栈!

重新梳理思路,
第二层我们依旧左子节点先入栈,右子节点后入栈,这样,在第三层时我们就可以先获得右子节点。
第三层,当前栈顶为右子节点,我们必须让右子节点的右孩子先入栈,左孩子后入栈。右子节点处理后,就是左子节点,左子节点的右孩子先入栈,左孩子后入栈,这样下一层获取的时候,就是左孩子先获得了。
第四层,同样,先让左子孩子入栈,再让右孩子入栈。下一层就可以从右向左打印。
第五层,右孩子先入栈。。。

现在就可以总结出来规律了,第二层左子节点先入栈,下一层就是右子节点先入站,再下一层是左子节点先入站。所以每一次都是取反!只要当前的boolean值是true,我们就让它从左向右的入栈,false,就从右向左的入栈。
而每一层的操作都是一个递归的过程。

  public static List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if(root == null) return result;

        Stack<TreeNode> stack  = new Stack<>();
        stack.push(root);
        boolean leftGoRight = true;
        printLikeZ(result,stack,leftGoRight);
        return result;
    }
    public static void printLikeZ(List result,Stack<TreeNode> stack,boolean leftGoRight){
        //保存下一层的节点
        Stack<TreeNode> newStack = new Stack();
        //保存当前节点的值
        ArrayList<Integer>  currentVaules = new ArrayList<>();
        while(!stack.isEmpty()){
            TreeNode current = stack.pop();
            currentVaules.add(current.val);
            //如果当前的是从左向右的保存子节点
            if(leftGoRight){
                if(current.left != null)
                    newStack.push(current.left);
                if(current.right != null)
                    newStack.push(current.right);

            }
            //如果不是
            else{
                if(current.right != null)
                    newStack.push(current.right);
                if(current.left != null)
                    newStack.push(current.left);
            }
        }
        //如果当前保存的节点值个数不为0,那么就将其加入结果集
        if(!currentVaules.isEmpty()){
            result.add(currentVaules);
        }
        //如果有下一个节点,那么就递归
        if(!newStack.isEmpty()){
            //下一次按反向入栈。
            printLikeZ(result,newStack,!leftGoRight);
        }


    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值