Interview AiBoxInterview AiBox 实时 AI 助手,让你自信应答每一场面试
如何实现二叉树的层序遍历?
题型摘要
层序遍历是二叉树遍历的一种方式,按照从上到下、从左到右的顺序逐层访问节点。它通常使用队列实现,基本思路是:先将根节点入队,然后循环执行出队访问、子节点入队的操作,直到队列为空。时间复杂度为O(n),空间复杂度为O(w),其中n是节点数,w是树的最大宽度。层序遍历有多种变体,如自底向上遍历、锯齿形遍历等,只需在基础算法上稍作修改即可实现。
二叉树的层序遍历实现
定义与原理
层序遍历(Level Order Traversal)是二叉树遍历的一种方式,按照从上到下、从左到右的顺序逐层访问树中的所有节点。这种遍历方式也称为广度优先搜索(Breadth-First Search, BFS)。
层序遍历的核心思想是使用队列(Queue)数据结构来辅助实现,通过队列的先进先出(FIFO)特性保证节点按照层级顺序被访问。
实现方法
基本算法步骤
- 将根节点放入队列
- 当队列不为空时,执行以下操作:
- 取出队首节点并访问
- 将该节点的左子节点(如果存在)加入队列
- 将该节点的右子节点(如果存在)加入队列
- 重复步骤2,直到队列为空
分层存储的层序遍历
如果需要将每一层的节点分开存储(例如返回一个二维数组,其中每个子数组代表一层),可以在上述算法基础上增加一个记录当前层节点数的步骤:
- 将根节点放入队列
- 当队列不为空时:
- 记录当前队列大小(即当前层的节点数)
- 创建一个临时数组存储当前层的节点值
- 循环处理当前层的所有节点:
- 取出队首节点,将其值加入临时数组
- 将其左右子节点加入队列
- 将临时数组加入结果数组
- 返回结果数组
代码实现
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;
}
}
可视化表示
层序遍历过程
二叉树层序遍历示例
复杂度分析
- 时间复杂度: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
参考资源
- LeetCode 102. 二叉树的层序遍历: https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
- GeeksforGeeks - Binary Tree Level Order Traversal: https://www.geeksforgeeks.org/level-order-tree-traversal/
- 算法图解 - 层序遍历: https://github.com/azl397985856/leetcode/blob/master/problems/102.binary-tree-level-order-traversal.md
思维导图
Interview AiBoxInterview AiBox — 面试搭档
不只是准备,更是实时陪练
Interview AiBox 在面试过程中提供实时屏幕提示、AI 模拟面试和智能复盘,让你每一次回答都更有信心。
AI 助读
一键发送到常用 AI
层序遍历是二叉树遍历的一种方式,按照从上到下、从左到右的顺序逐层访问节点。它通常使用队列实现,基本思路是:先将根节点入队,然后循环执行出队访问、子节点入队的操作,直到队列为空。时间复杂度为O(n),空间复杂度为O(w),其中n是节点数,w是树的最大宽度。层序遍历有多种变体,如自底向上遍历、锯齿形遍历等,只需在基础算法上稍作修改即可实现。
智能总结
深度解读
考点定位
思路启发
相关题目
请做一个自我介绍
自我介绍是HR面试的开场问题,考察表达能力、逻辑思维、自我认知、岗位匹配度和沟通技巧。有效的自我介绍应包含基本信息、教育背景、专业技能、项目/实习经历、个人特质与岗位匹配、求职动机与未来规划。表达时应控制时间在2-3分钟,语言简洁,重点突出,真诚自然。针对客户端开发岗位,应强调相关技术栈、项目经验和注重细节的特质。避免内容过于简单或冗长,缺乏针对性,过度夸大或缺乏逻辑性。建议提前准备、反复练习、突出亮点、保持真实并积极互动。
你的期望薪资是多少?
回答"期望薪资"问题需先做市场调研和自我评估,面试时应表达对职位的兴趣,提供合理薪资范围而非具体数字,强调综合考量整体薪酬包和发展机会,保持灵活态度并适时反问公司预算。避免过低或过高报价,关注长远职业发展。
请做一个自我介绍,包括你的教育背景、技术栈和项目经验。
自我介绍应包含教育背景、技术栈和项目经验三部分。首先简述基本信息,然后详细介绍与岗位相关的教育经历,清晰列出掌握的技术及熟练程度,选择2-3个代表性项目按STAR法则描述。最后强调个人优势与职业规划,表达对公司的向往。整个介绍应控制在3-5分钟,保持真实、有针对性,自信表达,并准备好对介绍内容的深入回答。
请详细介绍你的项目背景、技术选型、实现难点以及你的具体贡献。
这个问题要求面试者介绍项目背景、技术选型、实现难点和个人贡献。回答时应简明扼要地介绍项目目标和规模,详细说明技术选型理由,分析遇到的技术难点及解决方案,并清晰阐述个人在项目中的角色和贡献。通过展示项目经验、技术决策能力、问题解决能力和团队协作能力,全面体现面试者的综合素质和专业水平。
你在大学期间哪门计算机课程学得最好?为什么?
在大学期间,我学得最好的课程是数据结构与算法。通过理论与实践结合的学习方法,我深入掌握了各种数据结构和算法的核心知识点,并将这些知识应用到多个实际项目中。这些知识对客户端开发尤为重要,可以帮助优化性能、提升用户体验、有效管理内存和优化界面渲染。我持续学习算法的热情和扎实的基础,将帮助我在客户端开发实习中做出贡献。