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是树的最大宽度。层序遍历有多种变体,如自底向上遍历、锯齿形遍历等,只需在基础算法上稍作修改即可实现。
智能总结
深度解读
考点定位
思路启发
相关题目
请解释堆排序的原理和实现步骤。
堆排序是一种基于二叉堆数据结构的排序算法,通过构建最大堆并不断将堆顶元素与末尾元素交换实现排序。其时间复杂度稳定在O(n log n),空间复杂度为O(1),是不稳定的原地排序算法。主要步骤包括构建最大堆、交换堆顶和末尾元素、调整堆并重复该过程。堆排序适用于需要稳定时间复杂度和低空间复杂度的场景,但缓存性能较差,不适合小规模数据。
对称加密和非对称加密有什么区别?
对称加密和非对称加密是两种主要的加密技术。对称加密使用同一密钥进行加密和解密,速度快但密钥管理困难;非对称加密使用公钥和私钥对,密钥分发简单但速度慢。实际应用中常结合使用,如SSL/TLS协议,用非对称加密交换密钥,用对称加密传输数据。
请详细讲解A*寻路算法的原理和实现。你还了解哪些其他的寻路算法?在开放世界游戏中,应该如何设计寻路系统?
A*寻路算法是一种高效的路径查找算法,通过评估函数f(n)=g(n)+h(n)来选择最优节点,结合了Dijkstra算法的保证最短路径和贪心搜索的高效性。其他常见寻路算法包括Dijkstra算法、广度优先搜索、深度优先搜索、贪心最佳优先搜索、跳点搜索、流场寻路、导航网格和分层寻路等。在开放世界游戏中,寻路系统设计应采用分层架构,结合导航网格技术,实现预计算和缓存,处理动态障碍物,使用多线程和异步处理,优化路径平滑,并考虑特殊区域处理和性能优化,同时提供完善的工具支持。
这些排序算法的时间复杂度和空间复杂度分别是多少?
排序算法的时间复杂度和空间复杂度是衡量算法效率的重要指标。常见排序算法中,冒泡、选择和插入排序时间复杂度为O(n²),空间复杂度为O(1);快速、归并和堆排序平均时间复杂度为O(n log n),其中快速排序最坏情况为O(n²),归并排序空间复杂度为O(n),堆排序为O(1);计数、基数和桶排序属于非比较排序,时间复杂度可达到线性级别,但适用场景有限。选择排序算法时需考虑数据规模、内存限制、稳定性要求和数据特性等因素。
请做一个自我介绍
自我介绍是HR面试的开场问题,考察表达能力、逻辑思维、自我认知、岗位匹配度和沟通技巧。有效的自我介绍应包含基本信息、教育背景、专业技能、项目/实习经历、个人特质与岗位匹配、求职动机与未来规划。表达时应控制时间在2-3分钟,语言简洁,重点突出,真诚自然。针对客户端开发岗位,应强调相关技术栈、项目经验和注重细节的特质。避免内容过于简单或冗长,缺乏针对性,过度夸大或缺乏逻辑性。建议提前准备、反复练习、突出亮点、保持真实并积极互动。