Interview AiBox logo

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

download免费下载
2local_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

相关题目

请做一个自我介绍

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

arrow_forward

你的期望薪资是多少?

回答"期望薪资"问题需先做市场调研和自我评估,面试时应表达对职位的兴趣,提供合理薪资范围而非具体数字,强调综合考量整体薪酬包和发展机会,保持灵活态度并适时反问公司预算。避免过低或过高报价,关注长远职业发展。

arrow_forward

请做一个自我介绍,包括你的教育背景、技术栈和项目经验。

自我介绍应包含教育背景、技术栈和项目经验三部分。首先简述基本信息,然后详细介绍与岗位相关的教育经历,清晰列出掌握的技术及熟练程度,选择2-3个代表性项目按STAR法则描述。最后强调个人优势与职业规划,表达对公司的向往。整个介绍应控制在3-5分钟,保持真实、有针对性,自信表达,并准备好对介绍内容的深入回答。

arrow_forward

请详细介绍你的项目背景、技术选型、实现难点以及你的具体贡献。

这个问题要求面试者介绍项目背景、技术选型、实现难点和个人贡献。回答时应简明扼要地介绍项目目标和规模,详细说明技术选型理由,分析遇到的技术难点及解决方案,并清晰阐述个人在项目中的角色和贡献。通过展示项目经验、技术决策能力、问题解决能力和团队协作能力,全面体现面试者的综合素质和专业水平。

arrow_forward

你在大学期间哪门计算机课程学得最好?为什么?

在大学期间,我学得最好的课程是数据结构与算法。通过理论与实践结合的学习方法,我深入掌握了各种数据结构和算法的核心知识点,并将这些知识应用到多个实际项目中。这些知识对客户端开发尤为重要,可以帮助优化性能、提升用户体验、有效管理内存和优化界面渲染。我持续学习算法的热情和扎实的基础,将帮助我在客户端开发实习中做出贡献。

arrow_forward

阅读状态

阅读时长

5 分钟

阅读进度

6%

章节:16 · 已读:0

当前章节: 定义与原理

最近更新:2025-09-05

本页目录

Interview AiBox logo

Interview AiBox

AI 面试实时助手

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

免费下载download

分享题目

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

外部分享