题目描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
思路
用队列装每层的结点:
- 先把根结点加入队列,
- 然后设置两个索引:start用来遍历一行里面所有的结点,end指向每一层最后一个位置
- 当队列不空的时候,重复以下操作。
(1) 弹出一个元素。作为当前的根节点。
(2)如果根节点有左孩子,访问左孩子,并将左孩子入队。
(3)如果根节点有右孩子,访问右孩子,并将右孩子入队。 - 判断何时换行:当start索引指向end时,表明改行遍历结束可以开始新的一行了
开始新的一行需要把start、end和存放每一行结果的list容器重设为初始状态
实现
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
public class Solution {
ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<Integer> list=new ArrayList<>(); //存放每行结点的值
ArrayList<ArrayList<Integer>> res=new ArrayList<>(); //存放最终多行结点
Queue<TreeNode> q=new LinkedList<>(); //队列存放一行的结点
if(pRoot==null) return res;
//第一层只有根结点,把根结点加入队列
q.offer(pRoot);
int start=0; //每一层开始位置,作为索引,不断向后遍历结点,直到该层结束
int end=1; //每一层最后一个位置 (初始是第二层)
while(!q.isEmpty()){
//定义当前遍历到的结点作为接下来的根结点,并把它弹出队列,加入list
TreeNode cur=q.remove();
list.add(cur.val);
start++; //start索引向后移动
//再看当前根结点是否有左子树,有就把左节点加入队列
if(cur.left!=null){
q.offer(cur.left);
}
//再看当前根结点是否有右子树,有就把右节点加入队列
if(cur.right!=null){
q.offer(cur.right);
}
//判断何时换行————start遍历到某一行的end位置时,说明该换行了
if(start==end){
//把已完成的一行加入到最终结果
res.add(list);
//开始新的一行:把各参数恢复成初始
start=0;
end=q.size();
list=new ArrayList<Integer>();
}
}
return res;
}
}