用deque而非list模拟队列因list.pop(0)为o(n),导致层次遍历退化至o(n²),而deque.popleft()为o(1);需用len(q)固定层大小、跳过none节点、判空用if q:,并严格检查node非空再访问子节点。

为什么用 collections.deque 而不是列表模拟队列
用普通 list 的 pop(0) 做出队操作是 O(n) 时间复杂度,层次遍历中每访问一个节点都触发一次,整体退化到 O(n²)。而 deque 的 popleft() 是 O(1),适合高频进出场景。
常见错误现象:list.pop(0) 在大数据量下明显卡顿,甚至超时;用 queue.Queue 反而引入线程安全开销,纯单线程场景没必要。
- 导入方式固定写
from collections import deque - 初始化:
q = deque([root]),注意传入可迭代对象(哪怕只有一个元素也要加方括号) - 判空统一用
if q:,不要用len(q) > 0
如何正确处理空节点和分层边界
层次遍历的核心难点不是“访问”,而是“知道当前在哪一层”。不显式记录层级信息,就无法区分 [3,9,20,null,null,15,7] 中的 9 和 20 是否同层。
推荐做法:每次循环开始前,先记下当前队列长度 level_size = len(q),然后只 pop 这么多次——这恰好对应当前层所有节点。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 不能在 for 循环里动态调
len(q),因为子节点正不断加入 - 遇到
None节点直接跳过,不 append 其左右子节点(否则会把空指针带入下一层) - 如果题目要求返回二维列表(每层一个子列表),就在每轮 level_size 循环内收集值
TreeNode 结构与输入兼容性要点
LeetCode 风格的 TreeNode 通常含 val、left、right 三个属性,但实际项目中可能用字典或命名元组。遍历时必须确保访问 node.left 前判断 node 非空。
典型错误:未检查 node 就直接取 node.left,抛出 AttributeError: 'NoneType' object has no attribute 'left'。
- 入口处必须判
if not root: return [] - 入队前检查:
if node.left:再q.append(node.left) - 不要依赖
isinstance(node, TreeNode)做类型兜底——实际数据可能混入dict或None
要不要用递归实现层次遍历
可以,但不推荐。递归本质靠栈,而层次遍历天然需要 FIFO,强行用递归需额外维护层级索引和结果容器,代码更绕、易错且无性能优势。
有人尝试用 DFS 记录 depth 参数再按层聚合,这属于“伪层次遍历”:它能产出正确结果,但访问顺序仍是深度优先,无法在遍历中途做层内剪枝(比如“找到某层第一个偶数就停止”)。
- 真正需要“访问即处理”的场景(如实时渲染树形 UI),必须用队列迭代
- 递归版本在 Python 中还有栈深度限制,树深超千层易报
RecursionError - 面试中写递归解法,大概率会被追问“怎么改成迭代”
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










