请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。例如给定二叉树: [3,9,20,null,null,15,7];输出
[ [3], [20,9], [15,7] ]。
按之字形打印,只需要能区分打印哪一层需要反转即可。因此引入一个flag变量,用来标记是否需要反转,同时集合采用LinkedList集合,支持从前或从后添加元素。
package learnproject.offer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/*
* 32.从上到下之字形打印二叉树
*/
public class Demo32_3{
/*
* 解题思路:
* 广度优先搜索算法只能通过队列来实现
* 例如遍历一棵平衡二叉树
* 1.第一次(1为奇数)遍历时,queue只有一个根节点,sublist只有根节点的val
* 2.第二次(2为偶数)遍历时,queue有根节点的左右子节点,队列长度为2,
* sublist需要打印子节点的val,
* 同时将子节点的子节点加入到队列中,但往sublist中写入数据的时候,
* 定义的队列长度为2,则只需要往sublist增加queue队列的前两个元素的val,
* 数据写入的顺序是从右往左(因此这里用LinkedList表示,可以从前或者从后添加元素)
* 3.以此类推
*/
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> list = new ArrayList<>();
if(root == null) {
return list;
}
//LinkedList实现了Queue的接口
Queue<TreeNode> queue = new LinkedList<TreeNode>();
//添加根节点
queue.add(root);
int j=0;
boolean flag = false;
while(!queue.isEmpty()) {
LinkedList<Integer> sublist = new LinkedList<Integer>();
int length = queue.size();
j++;
if(j % 2 == 1) {
flag = true;
}else {
flag = false;
}
for(int i=0;i<length;i++) {
//队头结点弹出
TreeNode treeNode = queue.poll();
TreeNode leftNode = treeNode.left;
if(leftNode!=null) {
//将左结点加入
queue.add(leftNode);
}
TreeNode rightNode = treeNode.right;
if(rightNode != null) {
//将右结点加入
queue.add(rightNode);
}
if(flag) {
sublist.add(treeNode.val);
}else {
sublist.addFirst(treeNode.val);
}
}
list.add(sublist);
}
return list;
}
public static void main(String args[]) {
TreeNode treeNode1 = new TreeNode(3);
TreeNode treeNode2 = new TreeNode(9);
TreeNode treeNode3 = new TreeNode(20);
TreeNode treeNode4 = new TreeNode(15);
TreeNode treeNode5 = new TreeNode(7);
treeNode1.left = treeNode2;
treeNode1.right = treeNode3;
treeNode3.left = treeNode4;
treeNode3.right = treeNode5;
Demo32_3 demo = new Demo32_3();
List<List<Integer>> list = demo.levelOrder(treeNode1);
System.out.println("hello world");
}
}