递归需首行判空,迭代前序压栈先右后左,中序用左探+回溯,层序必用deque,调试应补__repr__或tree_to_list。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

递归写法里 root 为空时直接 return,别漏判 None
二叉树遍历最常崩在空节点访问,比如写 root.left 前没确认 root 是否为 None,一跑就报 AttributeError: 'NoneType' object has no attribute 'left'。Python 里尤其容易踩这个坑,因为语言不强制类型检查,错误拖到运行时才暴露。
实操建议:
- 所有递归函数入口第一行写
if not root: return(或对应语言的空值判断) - 中序/前序/后序三者结构一致,只差打印或处理节点的时机,别为了“省一行”把判空和逻辑混在一起
- 如果用类型提示(如
Optional[TreeNode]),IDE 能提前标出潜在空解引用,但不能替代运行时判断
stack 模拟递归时,先压 right 再压 left 才能保证左子树先处理
用栈写迭代版前序遍历,顺序错一点结果全乱。常见错误是按直觉先压 left 再压 right,结果弹出来反而是右子树优先——因为栈是后进先出。
实操建议:
- 前序迭代:每次 pop 后,
if node.right: stack.append(node.right),再if node.left: stack.append(node.left) - 中序迭代不能靠简单改压栈顺序,必须用“一路向左+记录回溯点”模式,否则逻辑会绕晕
- 迭代写法比递归多 2–3 倍代码量,调试时建议先 print 栈变化,比硬想更可靠
层序遍历用 deque 而不是 list,否则 popleft() 变 O(n)
用 Python 写 BFS 时,如果直接用 list.pop(0) 模拟队列头出,每次操作实际是移动整个列表,单次时间复杂度变成 O(n),整棵树遍历退化成 O(n²)。小数据看不出来,节点一多就卡死。
实操建议:
- 务必从
collections导入deque,调用popleft()和append() - 不要用
list的insert(0, x)或pop(0),它们底层都是内存搬移 - 如果环境受限不能用
deque(比如某些嵌入式 Python),改用两个list轮换(当前层 / 下一层),避免任何0位置操作
LeetCode 上 TreeNode 类没有 __repr__,调试时自己补一个
刷题时 print 出来的 TreeNode 对象就是 <__main__.treenode object at></__main__.treenode>,完全看不出结构。手动展开又累又易错,尤其遇到深度大、分支多的树。
实操建议:
- 在本地测试文件开头加一段:
def __repr__(self): return f'TreeNode({self.val})'(加到类定义里) - 更实用的是写个辅助函数
tree_to_list(root),把树转成 LeetCode 输入格式那种层级数组,一眼看清结构 - 别依赖 IDE 的变量查看器——它对链式结构展示很弱,且线上环境根本没这功能










