按之字形顺序打印二叉树(树遍历,stack,queue结合使用)

该博客详细介绍了如何利用栈和队列按之字形顺序打印二叉树。首先,栈用于主要遍历,队列作为辅助。通过改变遍历方向(左到右或右到左),结合栈的后进先出特性,实现了从上到下、从左到右再到左的层次遍历。每层节点先入栈,然后出栈并添加到结果列表,最后将当前层的子节点按顺序入队,准备下一次遍历。这种方法巧妙地利用了数据结构特性,实现了二叉树的特殊遍历方式。
摘要由CSDN通过智能技术生成

按之字形顺序打印二叉树_牛客题霸_牛客网

1."之""字行说明每一层的顺序是不一样的,第一层是从左到右,第二层就是从右到左

2.实际上每一层的顺序不一样,但是还是按照层序遍历的方式来遍历层的

3.层序遍历一般用到队列 ,但是这个顺序有时候是逆序,我们联想到的数据结构就是栈

4.整体思路:

  • 首先你要有栈和队列,栈为主,队列为辅
  • 你定义dir = 1 或者2 是为了去分辨这一层是左遍历还是右遍历
  • 你把根节点入到栈去,然后记录栈中的元素个数,for循环就是先去出栈,然后得到栈顶元素val,此时再把这个出栈的左右子树入到队列中去,直到这个栈出完
  • 你出栈的顺序实际上是你入栈的逆序,你这一层出栈是 dir = 1,从左到右,那么你把这个顺序衍生到下一层的入栈顺序,那么你下一层出栈顺序就是逆序了
  • 这里通过队列作为中间商,先入到队列中去(因为出入队列的顺序是一致的),然后把队列中的元素(就是上一层的元素)全部入到栈中去,接下来通过while循环,不断就遍历下一层
  • 别忘了每走完一层  dir 都需要改变一下
import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        ArrayList<Integer> list = new ArrayList<>();
        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
        if(pRoot == null){
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        Queue<TreeNode> q =  new LinkedList<>();
        stack.push(pRoot);
        int dir = 1;
        while(!stack.isEmpty()){
            int size = stack.size();
            for(int i = 0;i < size;i++){
                //先去把stack 中的元素全部出栈
                TreeNode node = stack.pop();
                list.add(node.val);
                TreeNode first = (dir == 1) ? node.left : node.right;
                TreeNode second = (dir == 1)? node.right: node.left;
                if(first != null) q.offer(first);
                if(second != null) q.offer(second);
                //这里执行一次循环实际上是将一个节点val放到list中,然后这个节点的左右子树
                //根据dir的值进行顺序入队列
            }
            //一个for循环结束意味着这一层的出栈下一层的入队列都结束了
            result.add(new ArrayList(list));
            list.clear();
            //此时我们就去把存储在队列中的这一层入到栈中
            while(!q.isEmpty()){
                stack.push(q.poll());
            }
            dir = (dir == 1) ? 2 : 1;
        }
        return result;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值