树结构遍历问题求助:如何打印所有节点的quantity值?现有预遍历代码存在多子节点无法输出及报错问题
问题分析与修复方案
嘿,我看你遇到了树结构预遍历的问题——当节点有2个以上子节点时,后面的quantity打不出来还报错。咱们来一步步拆解问题,然后搞定它。
原代码的问题所在
先瞅瞅你的预遍历函数:
function preOrder(tree) { var qntChildren = 0 try{ console.log(tree.quantity) if (tree.childrens || tree.quantity) { preOrder(tree.childrens[0]) } }catch(e) { preOrder(tree.childrens[qntChildren + 1]) } } preOrder(treeModel)
这里有几个致命的逻辑问题:
- 只死磕第一个子节点:你在
try块里只调用了preOrder(tree.childrens[0]),完全没处理其他子节点的遍历,这就导致除了第一个子节点,剩下的都被忽略了。 - 错误处理逻辑完全跑偏:
catch块里想用qntChildren + 1来遍历下一个子节点,但qntChildren是函数内部的局部变量,每次调用函数都会重置成0,根本没法正确递增索引。而且当子节点都遍历完了,你还硬要访问tree.childrens[qntChildren + 1],自然会拿到undefined,再去访问它的childrens可不就报错了嘛。 - 判断条件逻辑混乱:
if (tree.childrens || tree.quantity)这个条件完全不对,tree.quantity是你要打印的目标,肯定是存在的,所以这个条件永远为真,哪怕节点没有子节点,也会硬着头皮去访问tree.childrens[0],这也是报错的诱因之一。
修复后的正确预遍历函数
正确的预遍历逻辑应该是:先打印当前节点的quantity,然后遍历所有子节点,对每个子节点递归调用预遍历函数。这样不管有多少个子节点,都能被挨个处理到。
修改后的代码如下:
function preOrder(tree) { // 先打印当前节点的quantity console.log(tree.quantity); // 先检查有没有子节点,并且子节点数组不为空 if (tree.childrens && tree.childrens.length > 0) { // 遍历所有子节点,逐个递归调用 for (const child of tree.childrens) { preOrder(child); } } } preOrder(treeModel);
测试效果
用你提供的treeModel测试:
var treeModel = { "quantity": 5, "childrens": [ { "quantity": 3, "childrens": [ { "tech": "B", "quantity": 1, "childrens": [] }, { "tech": "C", "quantity": 4, "childrens": [] }, { "tech": "C", "quantity": 6, "childrens": [] } ] } ] }
运行后会输出:
5 3 1 4 6
完全符合预遍历的预期,再也不会出现报错啦。
额外补充:迭代版实现(避免递归深度问题)
如果你的树结构特别深,递归可能会导致栈溢出,这时候可以用栈来模拟预遍历:
function preOrderIterative(tree) { const stack = [tree]; while (stack.length > 0) { const node = stack.pop(); console.log(node.quantity); // 因为栈是后进先出,所以要逆序推入子节点,保证遍历顺序和递归一致 for (let i = node.childrens.length - 1; i >= 0; i--) { stack.push(node.childrens[i]); } } }
这个版本和递归版本的输出顺序完全一致,适合处理超大、超深的树结构。
内容的提问来源于stack exchange,提问作者amorim
相关产品推荐
相关产品推荐

