算法4--分奇偶行打印二叉树--队列的应用

头条的一道面试题,层序打印二叉树,奇数行时从左到右,偶数行时从右到左。

如上所示,打印结果为 :

  1 

  3  2

  4   5   6   7

  10   9  8

1. 普通的层序打印二叉树,一般采用一个队列,根节点入队列,然后一次遍历队列中的节点,打印每一个节点值,同时若该节点左右节点非空,继续入队列:

public static void levelOrder(TreeNode root){
		if(root==null) return;
		Queue<TreeNode> q = new LinkedList<>();
		q.add(root);
		TreeNode tmp = null;
		while(!q.isEmpty()){
			tmp = q.poll();
			System.out.println(tmp.val);
			if(tmp.left!=null)
				q.add(tmp.left);
			if(tmp.right!=null)
				q.add(tmp.right);
		}
	}

2.刚开始我的解法是进行一遍BFS,把二叉树的遍历结果保存在一个List<List<Integer>>,其中二叉树的每一行对应List<List>的每一个元素List,然后遍历这个List<List>即可实现各种类型的打印效果,代码如下:

public static void levelOrder2(TreeNode root){
		List<List<Integer>> ll = new ArrayList<>();
		bfs(root, ll, 0);
		System.out.println(ll);
		for(int i=0; i<ll.size(); i++){
			if(((i+1)&0x01)==1){
				System.out.println(ll.get(i));
			}else{
				List<Integer> l = ll.get(i);
				Collections.reverse(l);
				System.out.println(l);
			}
		}
	}
	
	public static void bfs(TreeNode node, List<List<Integer>> ll, int depth){
		if(node==null) return;
		if(depth>=ll.size()){
			List<Integer> l = new ArrayList<>();
			l.add(node.val);
			ll.add(l);
		}else{
			ll.get(depth).add(node.val);
		}
		bfs(node.left, ll, depth+1);
		bfs(node.right, ll, depth+1);
	}

这样做空间复杂度太大,需要把原来二叉树给复制一遍,后来又提示了一下,采用队列方式来实现。把每一行全部入队,然后分奇偶行来打印二叉树:

public static void levelOrder3(TreeNode root){
		if(root==null) return;
		Queue<TreeNode> q = new LinkedList<>();
		q.add(root);
		int level = 1;
		while(!q.isEmpty()){
			List<Integer> l = new ArrayList<>();
			int size = q.size();
			while(size>0){
				TreeNode tmp = q.poll();
				l.add(tmp.val);
				if(tmp.left!=null)
					q.add(tmp.left);
				if(tmp.right!=null)
					q.add(tmp.right);
				size--;
			}
			if((level&0x01)==1){
				System.out.println(l);
			}else{
				Collections.reverse(l);
				System.out.println(l);
			}
			level++;
		}
	}

在出队的同时,保留队列中元素值,同时当出对节点左右子节点非空时也要继续入队,这里提前需要有一个变量来记录上一行中节点数并依次递减来计数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值