携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
广度优先搜索
广度优先搜索(Breadth First Search)的核心思想就是按层搜索。先全部搜索完第一层,再检索第二层,只有等第二层节点全部被遍历过,才会向下层继续搜索。
如下图:按照广度优先搜索原则,第一个搜索到的是第一层的3,然后是第二层的9、20,最后是第三层15和7。
按层遍历二叉树
描述
以上图二叉树为例,我们翻译成数组root:[3,9,20,null,null,15,7],既然按层遍历,我们输出一个二维数组[[1],[9,20],[15,7]],外层数组中的每一个子数组代表一层。
需要注意的是,root结构类型是二叉树中最常用的链式存储结构,如下:
function TreeNode(val, left, right) {
this.val = (val===undefined ? 0 : val)
this.left = (left===undefined ? null : left)
this.right = (right===undefined ? null : right)
}
由于二叉树每个结点最多有两个子节点,所以最自然的想法就是为它设计一个数据域和两个指针域。
结点结构图如下表所示。其中data 为数据域,lchild和rchind是指针域,分别存放指向左子树和右子树的指针。
分析
- 二叉树为空则返回空数组
- 创建一个队列,开始放入顶层节点,再判断是否存在左右子节点,存在则不断放入队列中循环
- 每个循环周期仅遍历同一层级
代码
var levelOrder = function(root) {
const ret = [] // 定义返回数组
// 如果为空,则返回空数组
if (!root) {
return ret
}
const queue = []
queue.push(root) // 初始化队列
while (queue.length !== 0) {
const currentLevelSize = queue.length // 当前层节点的数量
ret.push([])
// 仅循环同一层级
for (let i = 1; i <= currentLevelSize; ++i) {
// 弹出queue的第一个元素
const node = queue.shift()
ret[ret.length - 1].push(node.val) // 推入当前层的数组
if (node.left) queue.push(node.left) // 判断左节点是否存在,存在左节点就继续加入队列
if (node.right) queue.push(node.right) // 判断右节点是否存在,存在右节点就继续加入队列
}
}
return ret
}