Interview AiBox logo

Interview AiBox 实时 AI 助手,让你自信应答每一场面试

download免费下载
基础local_fire_department19 次面试更新于 2025-09-05account_tree思维导图

如何实现二叉树的层序遍历?

lightbulb

题型摘要

层序遍历是二叉树遍历的一种方式,按照从上到下、从左到右的顺序逐层访问节点。它通常使用队列实现,基本思路是:先将根节点入队,然后循环执行出队访问、子节点入队的操作,直到队列为空。时间复杂度为O(n),空间复杂度为O(w),其中n是节点数,w是树的最大宽度。层序遍历有多种变体,如自底向上遍历、锯齿形遍历等,只需在基础算法上稍作修改即可实现。

二叉树的层序遍历实现

定义与原理

层序遍历(Level Order Traversal)是二叉树遍历的一种方式,按照从上到下、从左到右的顺序逐层访问树中的所有节点。这种遍历方式也称为广度优先搜索(Breadth-First Search, BFS)。

层序遍历的核心思想是使用队列(Queue)数据结构来辅助实现,通过队列的先进先出(FIFO)特性保证节点按照层级顺序被访问。

实现方法

基本算法步骤

  1. 将根节点放入队列
  2. 当队列不为空时,执行以下操作:
    • 取出队首节点并访问
    • 将该节点的左子节点(如果存在)加入队列
    • 将该节点的右子节点(如果存在)加入队列
  3. 重复步骤2,直到队列为空

分层存储的层序遍历

如果需要将每一层的节点分开存储(例如返回一个二维数组,其中每个子数组代表一层),可以在上述算法基础上增加一个记录当前层节点数的步骤:

  1. 将根节点放入队列
  2. 当队列不为空时:
    • 记录当前队列大小(即当前层的节点数)
    • 创建一个临时数组存储当前层的节点值
    • 循环处理当前层的所有节点:
      • 取出队首节点,将其值加入临时数组
      • 将其左右子节点加入队列
    • 将临时数组加入结果数组
  3. 返回结果数组

代码实现

Python实现

from collections import deque

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def levelOrder(root):
    if not root:
        return []
    
    result = []
    queue = deque([root])
    
    while queue:
        level_size = len(queue)
        current_level = []
        
        for _ in range(level_size):
            node = queue.popleft()
            current_level.append(node.val)
            
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
                
        result.append(current_level)
    
    return result

JavaScript实现

class TreeNode {
    constructor(val, left = null, right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

function levelOrder(root) {
    if (!root) return [];
    
    const result = [];
    const queue = [root];
    
    while (queue.length > 0) {
        const levelSize = queue.length;
        const currentLevel = [];
        
        for (let i = 0; i < levelSize; i++) {
            const node = queue.shift();
            currentLevel.push(node.val);
            
            if (node.left) queue.push(node.left);
            if (node.right) queue.push(node.right);
        }
        
        result.push(currentLevel);
    }
    
    return result;
}

Java实现

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) return result;
        
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        
        while (!queue.isEmpty()) {
            int levelSize = queue.size();
            List<Integer> currentLevel = new ArrayList<>();
            
            for (int i = 0; i < levelSize; i++) {
                TreeNode node = queue.poll();
                currentLevel.add(node.val);
                
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
            
            result.add(currentLevel);
        }
        
        return result;
    }
}

可视化表示

层序遍历过程

--- title: 二叉树层序遍历过程 --- graph TD A["开始: 根节点入队"] --> B["队列: [1]"] B --> C["出队1, 访问1"] C --> D["1的左右子节点2,3入队"] D --> E["队列: [2, 3]"] E --> F["出队2, 访问2"] F --> G["2的左右子节点4,5入队"] G --> H["队列: [3, 4, 5]"] H --> I["出队3, 访问3"] I --> J["3的左右子节点6,7入队"] J --> K["队列: [4, 5, 6, 7]"] K --> L["依次出队并访问4,5,6,7"] L --> M["队列为空, 遍历结束"]

二叉树层序遍历示例

--- title: 二叉树层序遍历示例 --- graph TD A["1"] --> B["2"] A --> C["3"] B --> D["4"] B --> E["5"] C --> F["6"] C --> G["7"] style A fill:#f9f,stroke:#333,stroke-width:2px style B fill:#bbf,stroke:#333,stroke-width:2px style C fill:#bbf,stroke:#333,stroke-width:2px style D fill:#bfb,stroke:#333,stroke-width:2px style E fill:#bfb,stroke:#333,stroke-width:2px style F fill:#bfb,stroke:#333,stroke-width:2px style G fill:#bfb,stroke:#333,stroke-width:2px

复杂度分析

  • 时间复杂度:O(n),其中 n 是二叉树中的节点数。我们需要访问每个节点一次。
  • 空间复杂度:O(w),其中 w 是二叉树的最大宽度(即最多节点的层的节点数)。在最坏情况下,当树是完全平衡时,最后一层包含大约 n/2 个节点,所以空间复杂度为 O(n)。

变体问题

自底向上的层序遍历

将层序遍历的结果反转即可实现自底向上的遍历。

def levelOrderBottom(root):
    if not root:
        return []
    
    result = []
    queue = deque([root])
    
    while queue:
        level_size = len(queue)
        current_level = []
        
        for _ in range(level_size):
            node = queue.popleft()
            current_level.append(node.val)
            
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
                
        result.append(current_level)
    
    return result[::-1]  # 反转结果

锯齿形层序遍历

奇数层从左到右,偶数层从右到左的遍历方式。

def zigzagLevelOrder(root):
    if not root:
        return []
    
    result = []
    queue = deque([root])
    left_to_right = True
    
    while queue:
        level_size = len(queue)
        current_level = [0] * level_size
        
        for i in range(level_size):
            node = queue.popleft()
            # 根据方向确定插入位置
            index = i if left_to_right else level_size - 1 - i
            current_level[index] = node.val
            
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
                
        result.append(current_level)
        left_to_right = not left_to_right
    
    return result

参考资源

account_tree

思维导图

Interview AiBox logo

Interview AiBox — 面试搭档

不只是准备,更是实时陪练

Interview AiBox 在面试过程中提供实时屏幕提示、AI 模拟面试和智能复盘,让你每一次回答都更有信心。

AI 助读

一键发送到常用 AI

层序遍历是二叉树遍历的一种方式,按照从上到下、从左到右的顺序逐层访问节点。它通常使用队列实现,基本思路是:先将根节点入队,然后循环执行出队访问、子节点入队的操作,直到队列为空。时间复杂度为O(n),空间复杂度为O(w),其中n是节点数,w是树的最大宽度。层序遍历有多种变体,如自底向上遍历、锯齿形遍历等,只需在基础算法上稍作修改即可实现。

智能总结

深度解读

考点定位

思路启发

auto_awesome

相关题目

请解释堆排序的原理和实现步骤。

堆排序是一种基于二叉堆数据结构的排序算法,通过构建最大堆并不断将堆顶元素与末尾元素交换实现排序。其时间复杂度稳定在O(n log n),空间复杂度为O(1),是不稳定的原地排序算法。主要步骤包括构建最大堆、交换堆顶和末尾元素、调整堆并重复该过程。堆排序适用于需要稳定时间复杂度和低空间复杂度的场景,但缓存性能较差,不适合小规模数据。

arrow_forward

对称加密和非对称加密有什么区别?

对称加密和非对称加密是两种主要的加密技术。对称加密使用同一密钥进行加密和解密,速度快但密钥管理困难;非对称加密使用公钥和私钥对,密钥分发简单但速度慢。实际应用中常结合使用,如SSL/TLS协议,用非对称加密交换密钥,用对称加密传输数据。

arrow_forward

请详细讲解A*寻路算法的原理和实现。你还了解哪些其他的寻路算法?在开放世界游戏中,应该如何设计寻路系统?

A*寻路算法是一种高效的路径查找算法,通过评估函数f(n)=g(n)+h(n)来选择最优节点,结合了Dijkstra算法的保证最短路径和贪心搜索的高效性。其他常见寻路算法包括Dijkstra算法、广度优先搜索、深度优先搜索、贪心最佳优先搜索、跳点搜索、流场寻路、导航网格和分层寻路等。在开放世界游戏中,寻路系统设计应采用分层架构,结合导航网格技术,实现预计算和缓存,处理动态障碍物,使用多线程和异步处理,优化路径平滑,并考虑特殊区域处理和性能优化,同时提供完善的工具支持。

arrow_forward

这些排序算法的时间复杂度和空间复杂度分别是多少?

排序算法的时间复杂度和空间复杂度是衡量算法效率的重要指标。常见排序算法中,冒泡、选择和插入排序时间复杂度为O(n²),空间复杂度为O(1);快速、归并和堆排序平均时间复杂度为O(n log n),其中快速排序最坏情况为O(n²),归并排序空间复杂度为O(n),堆排序为O(1);计数、基数和桶排序属于非比较排序,时间复杂度可达到线性级别,但适用场景有限。选择排序算法时需考虑数据规模、内存限制、稳定性要求和数据特性等因素。

arrow_forward

请做一个自我介绍

自我介绍是HR面试的开场问题,考察表达能力、逻辑思维、自我认知、岗位匹配度和沟通技巧。有效的自我介绍应包含基本信息、教育背景、专业技能、项目/实习经历、个人特质与岗位匹配、求职动机与未来规划。表达时应控制时间在2-3分钟,语言简洁,重点突出,真诚自然。针对客户端开发岗位,应强调相关技术栈、项目经验和注重细节的特质。避免内容过于简单或冗长,缺乏针对性,过度夸大或缺乏逻辑性。建议提前准备、反复练习、突出亮点、保持真实并积极互动。

arrow_forward

阅读状态

阅读时长

5 分钟

阅读进度

6%

章节:16 · 已读:0

当前章节: 定义与原理

最近更新:2025-09-05

本页目录

Interview AiBox logo

Interview AiBox

AI 面试实时助手

面试中屏幕实时显示参考回答,帮你打磨表达。

免费下载download

分享题目

复制链接,或一键分享到常用平台

外部分享