解决二叉树中广度优先搜索遍历的主要思路:
借助于队列
基础的BFS结构实现
void bfs(TreeNode root) {
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll(); // Java 的 pop 写作 poll()
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}
二叉树中BFS使用的两个主要场景
层序遍历
二叉树的层序遍历(从上到下)
题目描述
private static List<List<Integer>> levelOrderTraversal(TreeNode root) {
ArrayList<List<Integer>> res = new ArrayList<>();
// 层序遍历要求的输出结果和 BFS的输出结果是不同的。
// 层序遍历要求我们区分每一层,也就是返回一个二维数组 -> [[1], [2, 3], [4, 5]]。
// 而 BFS 的遍历结果是一个一维数组,无法区分每一层 -> [1, 2, 3, 4, 5]
if (root == null){
return res;
}
Queue<TreeNode> queue = new LinkedList<>();
// Queue 中 add() 和 offer()都是用来向队列添加一个元素。
// 在容量已满的情况下,add() 方法会抛出IllegalStateException异常,offer() 方法只会返回 false 。
queue.offer(root); // 向队列中添加元素
while (!queue.isEmpty()){
// 定义一个列表,存储每一层节点的值
List<Integer> levelRes = new ArrayList<>();
// 在开始遍历每一层的节点之前,先记录队列中节点的个数
int currentLevelSize = queue.size();
// 遍历当前层,获取当前层的所有的节点的val
for (int i = 0; i < currentLevelSize; i++) {
TreeNode node = queue.poll();
levelRes.add(node.val);
// 在获取当前层的节点的值的过程中,将下一层所有的节点加入到队列中
if (node.left != null){
queue.offer(node.left);
}
if (node.right != null){
queue.offer(node.right);
}
}
res.add(levelRes);
}
return res;
}
二叉树的层序遍历(从下向上)
题目描述
private static List<List<Integer>> ReverseLevelOrderTraversal(TreeNode root) {
// 相比于自上向下的层序遍历,这道题要求从下到上输出每一层的节点值。
// 只要对上述上一个题解的操作稍作修改即可:在遍历完一层节点之后,将存储该层节点值的列表添加到结果列表的头部。
// 为了降低在结果列表的头部添加一层节点值的列表的时间复杂度,这里就要求,存储结果的二维数组需要是链表的结构。
List<List<Integer>> res = new LinkedList<>();
if (root == null){
return res;
}
// 定义一个队列 用于存储每一层的节点
Queue<TreeNode> queue = new LinkedList<>();
// 将头结点(第一层的节点)加入到队列中
queue.offer(root);
while (!queue.isEmpty()){
// 创建一个存储结果的列表,为了降低时间复杂度,这里的列表使用链式结构
List<Integer> levelRes = new ArrayList<>();
// 获取当前层中节点个数
int currentLevelSize = queue.size();
for (int i = 0; i < currentLevelSize; i++) {
// 出队一个节点
TreeNode node = queue.poll();
levelRes.add(node.val);
if (node.left != null){
queue.offer(node.left);
}
if (node.right != null){
queue.offer(node.right);
}
}
// 将存储当前层节点值的列表添加到结果列表的头部
res.add(0, levelRes);
}
return res;
}
二叉树的右视图
题目描述
private static List<Integer> rightSideView(TreeNode root) {
// 创建一个返回结果集合
List<Integer> resList = new ArrayList<>();
if (root == null) {
return resList;
}
// 创建队列 用来存放节点
Queue<TreeNode> queue = new LinkedList<>();
// 将头结点放入到队列中
queue.offer(root);
while (!queue.isEmpty()) {
// 获取当前层的长度
int currentLevelLength = queue.size();
// 遍历当前层,将下一层的所有节点放入到队列中,并且将当前层最后一个节点值加入到返回结果集中
for (int i = 0; i < currentLevelLength; i++) {
// 取出节点
TreeNode node = queue.poll();
if (i == currentLevelLength - 1){
resList.add(node.val);
}
if (node.left != null){
queue.offer(node.left);
}
if (node.right != null){
queue.offer(node.right);
}
}
}
return resList;
}