最近刷剑指刷到了一系列关于树的层级遍历的问题,之前也没注意到过这类题,写的时候也没什么头绪。上b站搜了一下讲解看明白了,以此来记录一下自己的学习过程。(文中附视频参考链接)
首先例题如下图所示:
由于队列具有先进先出的特点,而我们在层级遍历时需要在出上一个父节点之后保存下左右子节点,且要保证父节点的兄弟节点要在其之前输出,故我们选择了一个辅助队列来进行一个循环的输出与保存。
中心思想:
- 根节点入队列
- 根节点出队列
- 安排左节点
- 安排右节点
本例题:
4入队列;
4出队列,并将值输出,控制台:4;
将4的左右子节点入队列,此时队列:2,6;
2出队列,并将值输出,此时队列:6,控制台:4,2;
将2的左右子节点入队列,此时队列:6,1,3;
6出队列,并将值输出,此时队列:1,3,控制台:4,2,6;
将6的左右子节点入队列,此时队列:1,3,5,7;
1出队列,并将值输出,此时队列:3,5,7,控制台:4,2,6,1;
1无子节点;
3,5,7依次出队列,并将值输出,控制台:4,2,6,1,3,5,7;
另附b站链接: link,感谢up主的详细说明,讲的非常透彻!
leetcode 剑指 Offer 32 - I 解题具体流程如下:
- 首先判断根节点是否为空,若为空,则直接返回一个新的空数组;
- 创建一个队列,并将根节点放入;
- 创建一个list,将输出的节点值保存下来(不直接使用数组是因为节点个数未知,未知长度数组后续无法操作);
- 节点出队列,并将当前节点的值保存在list中;
- 判断出队列的该节点是否有左右子节点,若有,则放入队列中;
- 循环4.5步骤,直到队列为空,即所有节点遍历结束;
- 创建与list大小等长的数组,并遍历list并赋值给新的数组;
- 返回数组。
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int[] levelOrder(TreeNode root) {
if(root == null) return new int[0];
List<Integer> list = new ArrayList<>();//保存节点值
Queue<TreeNode> que= new LinkedList<>();//辅助队列
que.add(root); //根节点入队
while(!que.isEmpty()){
TreeNode node = que.remove();//节点出队
if(node.left != null) que.add(node.left);//左节点入队
if(node.right != null) que.add(node.right);//右节点入队
list.add(node.val);//保存出队节点的值
}
int[] res = new int[list.size()];
for (int i = 0; i < res.length; i++) {
res[i] = list.get(i);
}
return res;
}
}
复习一下关于队列的一些方法:
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常。
offer 添加一个元素并返回true 如果队列已满,则返回false。
put 添加一个元素 如果队列满,则阻塞。
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常。
poll 移除并返问队列头部的元素 如果队列为空,则返回null。
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常。
peek 返回队列头部的元素 如果队列为空,则返回null。
take 移除并返回队列头部的元素 如果队列为空,则阻塞。