用JavaScript搞定二叉树的层序遍历(迭代 + 递归)

786 阅读2分钟

一、前言

此篇是关于二叉树的广度优先遍历(递归 + 迭代),想看二叉树的深度遍历,建议看我之前写的用JavaScript搞定二叉树的前中后序遍历

二、遍历顺序说明

关于层序遍历,大家可以看leetcode上102. 二叉树的层序遍历]的题目描述。我这里放一张leetcode题目描述的截图。

image.png

三、代码

git代码链接

  • 递归法:需要注意三点:递归函数的意义、递归结束条件、递归过程
  • 迭代法:维护一个队列(存每层的节点)

3.1 递归法


/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */


/**
 * 递归法:
 * 递归函数的意义:层序遍历以root为根节点的二叉树
 * 结束条件:root为空
 * 递归过程:层序遍历root的左子树、层序遍历root的右子树
 */

 const levelOrder = function (root) {
  //  层序遍历的结果数组
  const res = [];
  // 递归函数
  const __levelOrder = function (root, level, res) {
    // 递归结束条件
    if(root === null) return;
    
    // 把每层节点的值放入结果数组中(层数对应数组下标)
    if(res.length === level) res.push([]);
    res[level].push(root.val);

    // 层序遍历左子树
    __levelOrder(root.left, level + 1, res);
    // 层序遍历右子树
    __levelOrder(root.right, level + 1, res);
  }
  
  __levelOrder(root, 0, res);

  // 返回结果数组
  return res;
}

3.2 迭代法(队列)

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */

/**
 * BFS 指 广度优先搜索
 * 维护一个队列(存每层的节点)
 */

const levelOrder = function (root) {
  // 结构数组
  const res = [];
  
  // 空树,直接返回
  if(root === null) return res;

  // ********************* 代码到了这里说明是非空树 ***************************

  // 队列维护树的每层节点
  const queue = [];
  // 将根节点和他所对应的层数入队列
  queue.push({node: root, level: 0});

  // 循环队列
  while(queue.length) {
    // 出队
    const {node, level} = queue.shift();

    // 将出队的节点的值存到res中
    if(res.length === level) res.push([]);
    res[level].push(node.val);
    
    // 若当前节点有左子树,将其入队
    if(node.left) queue.push({node: node.left, level: level + 1});
    // 若当前节点有右子树,将其入队
    if(node.right) queue.push({node: node.right, level: level + 1});
  }

  // 返回结果数组
  return res;
}