持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情
前言
昨天介绍了二叉树的深度优先遍历,说到遍历,二叉树还有一种遍历方式——广度优先遍历,也就是层序遍历。今天我们一起来探索一下这种方法。
层序遍历
二叉树的层序遍历就是一行一行从左到右遍历,每个节点只访问一次,是一种新的遍历方法。实现层序遍历算法的时候需要借助队列这种数据结构来实现。队列先入先出的特性就十分适用于层序遍历一层一层遍历的逻辑。
实现方式
- 定义一个队列(在程序里表现为一个数组)
- 将根节点push入队列中
- 将队列按顺序弹出(先入先出shift())并存储在临时数组中
- 每次shift()将节点左右孩子push入队列
- 遍历完一层将临时数组存入res(结果数组)中
- 重复这个过程,直到全部遍历完
层序遍历模板
var levelOrder = function(root) {
//二叉树的层序遍历
let res=[],queue=[];
queue.push(root);
if(root===null){
return res;
}
while(queue.length!==0){
// 记录当前层级节点数
let length=queue.length;
//存放每一层的节点
let cur=[];
for(let i=0;i<length;i++){
let node=queue.shift();
cur.push(node.val);
// 存放当前层下一层的节点
node.left&&queue.push(node.left);
node.right&&queue.push(node.right);
}
//把每一层的结果放到结果数组
res.push(cur);
}
return res;
};
拓展
通过这一个模板可以做很多类似的题
107. 二叉树的层序遍历 II - 力扣(LeetCode)
只需要将结果数组翻转一下:res.unshift(cur)
199. 二叉树的右视图 - 力扣(LeetCode)
需要判断层序遍历的时候是否遍历到最后的那个元素,如果是则放入res数组中。
637. 二叉树的层平均值 - 力扣(LeetCode)
这道题需要在遍历的时候取每一层的平均值存入res中返回。
429. N 叉树的层序遍历 - 力扣(LeetCode)
这道题不限于二叉树了,每个节点可能有大于两个孩子,所以不能用left right的方式将下一层的节点存入队列之中了。这时需要遍历节点的所有孩子,按从左到右的顺序存入队列中。
for(let item of node.children){
item&&queue.push(item);
}
515. 在每个树行中找最大值 - 力扣(LeetCode)
这道题需要在遍历每一层的时候找到这层的最大值,存入res中返回。
116. 填充每个节点的下一个右侧节点指针 - 力扣(LeetCode)
层次遍历的同时让前一个节点指向本个节点。
后记
学会层次遍历的规则后,可以解决很多问题。