为啥根变量最终会保留在 while 循环中生成的整个树的结果?

Posted

技术标签:

【中文标题】为啥根变量最终会保留在 while 循环中生成的整个树的结果?【英文标题】:Why does the root variable eventually keep the result of the whole tree which is made inside the while loop?为什么根变量最终会保留在 while 循环中生成的整个树的结果? 【发布时间】:2021-12-13 03:02:56 【问题描述】:

curr 变量在 while 循环的第一次迭代中引用了 root,但是从第二次迭代开始,curr 变量应该每次迭代都引用一个新创建的节点?

var TreeNode = function (value, left, right) 
    this.value = value;
    this.left = left;
    this.right = right;
;

function arrayToTree(array) 
    if (!array.length) return undefined;
    var root = new TreeNode(array.shift());
    var queue = [root];

    while (array.length) 
        var curr = queue.shift();
        var left = new TreeNode(array.shift());
        curr.left = left;
        queue.push(left);
        if (!array.length) break;
        var right = new TreeNode(array.shift());
        queue.push(right);
        curr.right = right;
    

    return root;
;

const ret = arrayToTree([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

console.log(ret);

【问题讨论】:

【参考方案1】:

root 变量仅引用根对象。这在扩展过程中不会改变。但在此过程中,该对象的leftright 属性值会发生变化(从null 变为新节点)。

在循环的第一次迭代中,curr 引用了与root 相同的对象,因此对curr 进行的任何更改都将被带到root:两个变量都可以访问相同单个对象。由于代码将curr.left 设置为新节点并将curr.right 设置为新节点,此时root.leftroot.right 已设置为新节点。

在下一次迭代中,curr 将引用其中一个新创建的节点(这些节点已经“附加”到root),同样的情况也发生在那里:当curr 发生突变时,我们实际上改变了一个节点可以从root 联系到。更深的节点通过其left 和/或right 属性引用的新节点进行扩展。

【讨论】:

“在下一次迭代中,curr 将引用那些新创建的节点之一(它们已经“附加”到根节点)......” 新创建的节点如何附加到根节点令人困惑。因此,新创建的节点正在成为根的属性,这就是一切正常的原因。谢谢!【参考方案2】:

我认为 trincot 回答了你的问题。如果不清楚,请发表评论。

但是,如果您想要一个不涉及突变的版本,您可以递归地执行此操作,方法是注意由索引 i 处的值形成的节点的左子节点是由索引 @ 处的值形成的节点987654322@ 和来自索引2 * i + 2 的值的右孩子,假设它们存在:

const toTree = (xs, i = 0) =>
  i >= xs .length
    ? undefined
    : value: xs [i], left: toTree (xs, 2 * i + 1), right: toTree (xs, 2 * i + 2)

console .log (toTree ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
.as-console-wrapper max-height: 100% !important; top: 0

这不使用您的 TreeNode 构造函数。除非它比显示的更多,否则我认为没有理由。但是如果我们需要使用它,我们可以替换它:

    : value: xs [i], left: toTree (xs, 2 * i + 1), right: toTree (xs, 2 * i + 2)

用这个:

    : new TreeNode (xs [i], toTree (xs, 2 * i + 1), toTree (xs, 2 * i + 2))

【讨论】:

以上是关于为啥根变量最终会保留在 while 循环中生成的整个树的结果?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用 PySimpleGUI 的 while 循环中对列表框的更新最终导致我的程序挂起?

如何在循环结束后将输入传送到 Bash while 循环并保留变量

Jmeter 在下一个线程循环中保留“结果变量名”的值

为啥while循环的执行速度会随时间变化?

为啥这个 switch 语句在运行时会结束 while 循环?

为啥javascript不会在while循环中堆叠