1.题目: (二叉树的层序遍历)
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
2. 示例
3.解答步骤
思路都在注释上! 请大家自主阅读程序!
⭐ 本篇注意点: 本算法采用什么?
答:通过BFS,广度优先搜索, 我们通过创建一个queue队列,以队列不为空为条件进行循环。
每次循环中 嵌套了一个for循环,该for循环终止条件是本层的结点个数
for循环做了两件事: 1.将本层结点值添加到一个集合中 2.判断本层所有结点的子树是否存在,并添加到queue中
当 for循环跑完后,本层结点值都添加了一个集合(subList)中,最后将该集合添加到返回的大集合中
并且queue中入队了本层所有结点的左右子树
假如本层结点无一个子树,则queue为空,树也就遍历结束了!
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
// 最返回的是一个集合 套着许多小集合
// 每个小集合就是一层的元素集合
// 通过BFS来解决此类问题
// 假如传进的 root为空
// 则直接返回空集合
if(root == null) {
return new ArrayList<>();
}
// 首先初始化一个 用户控制循环遍历的 队列 queue
Queue<TreeNode> queue = new LinkedList<>();
// 创建一个保存每层元素的二级集合 (每个Arraylist的元素都是一个存储整形的List集合)
List<List<Integer>> resList = new ArrayList<>();
// 假如不是空树,先入队根节点
queue.add(root);
// 当 queue为空时,表示已经到了最后一层
// 已经没有新的子结点被添加到queue中
while(!queue.isEmpty()) {
// 首先要获取每层的结点数
// 因为当执行到这里时
// 上一层的结点已经全部被取出了
// 这一层的结点也依次入队
int subLength = queue.size();
//创建一个用于存储每层结点数据的集合
List<Integer> subList = new ArrayList<>();
// 依次将queue中本层的结点出队,并入队到subList
// 并且出队的此结点如果有左右子结点,也入队到queue
// 因为我们的循环中断条件是这里添加元素的个数
// 也就是(入队本层的所有子结点)
// 假如本层所有节点均无子结点,
// 则queue将本层所有结点均出队后,queue就为空了,整颗树遍历完成
for(int i=0; i<subLength; i++) {
TreeNode node = queue.poll();
// 添加到本层的集合中,这里注意添加的是结点的值
subList.add(node.val);
// 假如该结点有左右子树,则将其添加到queue队列中
// 一定注意先添加左子树,再添加右子树
if(node.left != null) {
queue.add(node.left);
}
if(node.right != null) {
queue.add(node.right);
}
}
// for遍历的是一层的元素,存到subList
resList.add(subList);
}
// 最终返回 resList
return resList;
}
}