二叉树层序遍历:while(q[0])与while(q.length)的困惑
二叉树层序遍历:
while(q[0]) 与 while(q.length) 的差异解析 在解决二叉树层序遍历问题时,写出了如下JavaScript代码:
var levelOrder = function(root) { let q = [root], ans = [] while (q[0]) { let qlen = q.length; let row = []; for (let i = 0; i < qlen; i++) { let curr = q.shift() row.push(curr.val) if (curr.left) q.push(curr.left) if (curr.right) q.push(curr.right) } ans.push(row) } return ans };
疑问:为何使用while (q[0])能正常运行,换成while (q.length)却不行?两者的核心差异是什么?
核心差异拆解
1. while(q[0]) 的判断逻辑
q[0] 本质是检查队列首个元素是否为真值:
- 当输入
root为null时,初始队列q = [null],q[0]为null(假值),循环直接终止,返回空数组,符合题目要求。 - 当队列中存在有效节点时,
q[0]是二叉树节点(真值),循环正常执行;当所有节点处理完毕,队列变为空数组,q[0]为undefined(假值),循环终止。 - 全程不会出现拿到
null后尝试访问val属性的情况,避免了类型错误。
2. while(q.length) 的判断逻辑
q.length 仅检查队列元素数量是否大于0,但存在致命漏洞:
- 如果输入
root为null,初始队列q = [null],此时q.length = 1(大于0),循环会进入。 - 执行
q.shift()拿到null后,尝试row.push(curr.val)会直接抛出TypeError: Cannot read properties of null (reading 'val'),导致代码崩溃。 - 即使
root不为null,如果某个场景下队列中混入了null(比如误将空节点入队),同样会触发错误。
3. 适配while(q.length)的修正方案
如果想用q.length作为循环条件,只需要提前处理root为null的边界情况,确保队列中始终只有有效节点:
var levelOrder = function(root) { if (!root) return []; // 提前拦截空树场景 let q = [root], ans = [] while (q.length) { let qlen = q.length; let row = []; for (let i = 0; i < qlen; i++) { let curr = q.shift() row.push(curr.val) if (curr.left) q.push(curr.left) if (curr.right) q.push(curr.right) } ans.push(row) } return ans };
这样修改后,队列中永远不会出现null,q.length的判断就能安全运行。
内容的提问来源于stack exchange,提问作者Yujin Dong
相关产品推荐
相关产品推荐

