二叉树层序遍历有这一篇就够了!

3,381 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情

前言

昨天介绍了二叉树的深度优先遍历,说到遍历,二叉树还有一种遍历方式——广度优先遍历,也就是层序遍历。今天我们一起来探索一下这种方法。

层序遍历

二叉树的层序遍历就是一行一行从左到右遍历,每个节点只访问一次,是一种新的遍历方法。实现层序遍历算法的时候需要借助队列这种数据结构来实现。队列先入先出的特性就十分适用于层序遍历一层一层遍历的逻辑。

实现方式

  1. 定义一个队列(在程序里表现为一个数组)
  2. 将根节点push入队列中
  3. 将队列按顺序弹出(先入先出shift())并存储在临时数组中
  4. 每次shift()将节点左右孩子push入队列
  5. 遍历完一层将临时数组存入res(结果数组)中
  6. 重复这个过程,直到全部遍历完

层序遍历模板

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)

层次遍历的同时让前一个节点指向本个节点。

后记

学会层次遍历的规则后,可以解决很多问题。