You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么我编写的前序遍历(preorder traversal)代码返回空列表?

问题根因分析

你的代码核心问题是递归调用的目标方法错误,叠加成员变量被反复重置,最终导致你观察到的现象:

  • 你在preOrder遍历方法中递归调用的是入口方法preorderTraversal,而非preOrder本身
  • 每次调用preorderTraversal时,第一行代码list = new ArrayList<Integer>()都会把成员变量list指向一个新的空列表,之前存入的内容会直接被丢弃
测试用例执行流程拆解

你使用的测试用例为[1,null,2,3],我们逐步骤走一遍执行逻辑就能对应上你的输出结果:

第一个print(add之前打印)的输出逻辑

  1. 首次调用preorderTraversal(节点1),list被初始化为空列表,调用preOrder(节点1)
  2. 进入preOrder(节点1),第一个print输出[],节点非空,将1加入list,接下来调用preorderTraversal(节点1的左节点null)
  3. 进入preorderTraversal(null),第一行将list重置为新的空列表,调用preOrder(null)
  4. 进入preOrder(null),第一个print输出[],节点为空直接返回
  5. 回到preOrder(节点1)的逻辑,调用preorderTraversal(节点1的右节点2)
  6. 进入preorderTraversal(节点2),第一行将list重置为新的空列表,调用preOrder(节点2)
  7. 进入preOrder(节点2),第一个print输出[],节点非空,将2加入list,接下来调用preorderTraversal(节点2的左节点3)
  8. 进入preorderTraversal(节点3),第一行将list重置为新的空列表,调用preOrder(节点3)
  9. 进入preOrder(节点3),第一个print输出[],节点非空,将3加入list,接下来调用preorderTraversal(节点3的左节点null)
  10. 进入preorderTraversal(null),第一行将list重置为新的空列表,调用preOrder(null),print输出[]后返回
  11. 回到preOrder(节点3),调用preorderTraversal(节点3的右节点null)
  12. 进入preorderTraversal(null),第一行将list重置为新的空列表,调用preOrder(null),print输出[]后返回
    以上流程一共触发7次print,全部输出空列表,和你观察到的结果完全一致。

第二个print(add之后打印)的输出逻辑

print在add操作之后执行,每次add之后还没来得及保留结果,下一次调用preorderTraversal就会把list清空:

  1. 节点1加入list后print输出[1],随后调用左节点的preorderTraversal把list清空
  2. 处理节点2时,preorderTraversal先清空list,add 2之后print输出[2],随后调用左节点的preorderTraversal把list清空
  3. 处理节点3时,preorderTraversal先清空list,add 3之后print输出[3]
    所以最终输出三行各只有一个元素的列表,和你观察到的结果一致。
你的认知偏差点
  • 你误以为成员变量list初始化后不会被修改,但实际上你每次递归调用入口方法preorderTraversal时,都会主动给list赋值新的空列表,不是存在多个list对象,是同一个list引用被反复指向了新的空列表对象,旧列表的内容直接被丢弃。
  • 你混淆了递归调用的目标:前序遍历的递归逻辑应该直接调用preOrder处理子节点,入口方法preorderTraversal仅需要调用一次,用来完成初始化操作,不应该作为递归调用的目标。

内容的提问来源于stack exchange,提问作者user

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:45:08