题目描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
问题分析
二叉树的结构:
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
上一篇博客我讲解了按之字形打印二叉树,按层打印二叉树与之类似,只有两个区别。区别一是不用判断奇偶层,因为打印顺序是从左向右按序打印。(之字形操作一下好像也可以不用判断)区别二是使用的数据结构不同,全部从左向右打印的话利用队列FIFO(先进先出)的特点十分合适。
我的代码及讲解
具体的讲解在代码的注释中,按步骤看还是比较清晰的,采用队列的结构可以很好地保证按顺序打印,根节点不为空时,根节点入队列一,队列一中remove的元素的左右子树按从左向右的顺序入队列二,队列二中的元素也是从左向右相同。当队列一和队列二中的元素全部出队意味着二叉树遍历完成。代码如下:
public class Solution {
ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> result=new ArrayList<ArrayList<Integer>>();
//创建两个队列
Queue<TreeNode> que1=new LinkedList<>();
Queue<TreeNode> que2=new LinkedList<>();
//根节点判空操作,防止下面入队时报空指针异常
if(pRoot==null){
return result;
}
//先将根节点入队
que1.add(pRoot);
//循环条件,如果队列1,2中还存在元素,说明二叉树还没有完成遍历
while(!que1.isEmpty()||!que2.isEmpty()){
ArrayList<Integer> arr=new ArrayList<Integer>();
while(!que1.isEmpty()){
TreeNode t=que1.remove();
//将队列1出队元素的左右子结点按顺序入队列2
if(t.left!=null){
que2.add(t.left);
}
if(t.right!=null){
que2.add(t.right);
}
arr.add(t.val);
}
//这个while结束时意味着已经将这一层的结点遍历完成,如果arr不为空,则将他加入result。
if(!arr.isEmpty()) result.add(arr);
ArrayList<Integer> arr2=new ArrayList<Integer>();
while(!que2.isEmpty()){
TreeNode t=que2.remove();
//将队列2出队元素的左右子结点按顺序入队列1
if(t.left!=null){
que1.add(t.left);
}
if(t.right!=null){
que1.add(t.right);
}
arr2.add(t.val);
}
//这个while结束时意味着已经将这一层的结点遍历完成,如果arr2不为空,则将他加入result。
if(!arr2.isEmpty()) result.add(arr2);
}
return result;
}
}
别人的代码
链接:https://www.nowcoder.com/questionTerminal/445c44d982d04483b04a54f298796288?f=discussion
来源:牛客网
//用递归做的
public class Solution {
ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> list = new ArrayList<>();
depth(pRoot, 1, list);
return list;
}
private void depth(TreeNode root, int depth, ArrayList<ArrayList<Integer>> list) {
if(root == null) return;
//他这里写的是如果下一层存在元素,则新建一个arraylist
if(depth > list.size())
list.add(new ArrayList<Integer>());
//这里是说将本层的值加入对应层的arrlist中。
list.get(depth -1).add(root.val);
//分别对左右子树进行递归操作。
depth(root.left, depth + 1, list);
depth(root.right, depth + 1, list);
}
}
看明白了吗?
卧草!卧草?!你品,你细品,这位大佬写的很巧妙啊,用短短几行代码直接搞定,什么是差距,翻译翻译,什么TMD叫差距。
总结
也不知道自己是笨还是为啥,就只能想到一些“笨”办法,可能是积累太少了,头脑里完全没有想试着递归或者别的方法的概念。我还是先多做点积累吧,看看什么时候能量变,再看看量变能不能引起质变,加油,向各位大佬学习。