头条的一道面试题,层序打印二叉树,奇数行时从左到右,偶数行时从右到左。
如上所示,打印结果为 :
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++;
}
}
在出队的同时,保留队列中元素值,同时当出对节点左右子节点非空时也要继续入队,这里提前需要有一个变量来记录上一行中节点数并依次递减来计数。