广度优先搜索

247 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

广度优先搜索

广度优先搜索(Breadth First Search)的核心思想就是按层搜索。先全部搜索完第一层,再检索第二层,只有等第二层节点全部被遍历过,才会向下层继续搜索。

如下图:按照广度优先搜索原则,第一个搜索到的是第一层的3,然后是第二层的9、20,最后是第三层15和7。

image.png

按层遍历二叉树

描述

以上图二叉树为例,我们翻译成数组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是指针域,分别存放指向左子树和右子树的指针。

image.png

分析

  1. 二叉树为空则返回空数组
  2. 创建一个队列,开始放入顶层节点,再判断是否存在左右子节点,存在则不断放入队列中循环
  3. 每个循环周期仅遍历同一层级

代码

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
}