题目
如下图所示,给定一棵二叉树的头节点head,按层打印二叉树,打印结果如下所示:
1
2 3
4 5 6
7 8
分析
定义两个变量:
last: 表示正在打印的当前行的最右节点
nlast:表示下一行的最右节点
定义一个队列 queue ,首先让 last 指向头节点 1;然后将 1 存入队列 queue,弹出 1,并打印 1,往队列中放入 1 的结点的左孩子 2 并让 nlast 指向节点 2,往队列中放入 1 的右孩子 3 并让 nlast 指向节点3;
此时发现弹出的结点 1 与 last 相等,所以该换行了,令 last = nlast ,然后从队列中弹出 2 并打印,把结点2 的孩子存入队列,并令 nlast指向节点2的孩子,弹出节点 3 并打印,将节点3的孩子添加到队列,并令nlast指向节点3的孩子, 此时发现弹出的节点 3 就是last 节点,所以该换行了。以此类推
代码实现
import java.util.*;
/**
* 有一棵二叉树,请设计一个算法,按照层次打印这棵二叉树。
* 给定二叉树的根结点root,请返回打印结果,结果按照每一层一个数组进行储存,
* 所有数组的顺序按照层数从上往下,且每一层的数组内元素按照从左往右排列。
* 保证结点数小于等于500。
*/
public class EX_01 {
private class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
public int[][] printTree(TreeNode root) {
ArrayList<ArrayList<Integer>> rows = new ArrayList<>();
ArrayList<Integer> row = new ArrayList<>();
TreeNode last = root;//记录正在打印行的最后一个节点
TreeNode nlast = null;//记录下一行的最后一个节点
TreeNode temp = null;
ArrayDeque<TreeNode> queue = new ArrayDeque<>();
queue.add(root);//将根节点添加至队列
while (!queue.isEmpty()) {
temp = queue.poll();//获取队头元素
row.add(temp.val);
if (temp.left != null) {//添加左孩子并使nlast指向此处
queue.add(temp.left);
nlast = temp.left;
}
if (temp.right != null) {//添加右孩子并使nlast指向此处
queue.add(temp.right);
nlast = temp.right;
}
if (temp == last) {//判断当前行是否打印完毕
last = nlast;
rows.add(row);//将一行数据添加到结果中
row = new ArrayList<>();//新建一行
}
}
int[][] res = new int[rows.size()][];//结果转化成数组形式
for (int i = 0; i < rows.size(); i++) {
res[i] = new int[rows.get(i).size()];
for (int j = 0; j < res[i].length; j++) {
res[i][j] = rows.get(i).get(j);
}
}
return res;
}
}