【问题标题】:How is the Root Node being updated when child nodes are the ones updated when performing Tree modifications?当执行树修改时更新子节点时如何更新根节点?
【发布时间】:2022-01-08 15:55:17
【问题描述】:

如何使用我们执行的子更新来更新 Tree 的父节点?特别是当您执行 BFS 或 DFS 搜索时,在节点上执行检查,然后更新该节点。是什么导致内存或编程语言知道“哦,嘿,我也必须对根节点进行此更新!”

在我的示例中,我使用的是 Trie(不是很重要,但我将其称为树)。我在下面有这个 BFS 搜索,它搜索了一堆节点,并将使用特定的单词值进行更新。我的评论是我的问题所在。该子节点当前存储在“deque”中。程序如何知道我的意思是更新 Root 中的值,而不仅仅是传递给变量“deque”的值?

对我来说,我认为应该发生的是 Root 不应该被更新,唯一被更新的是变量“deque”,然后在它完成之后,一切都被垃圾收集并且 Root 保持不变。相反,当“deque”更新时,Root 也会更新。也许我在数据结构课程中错过了这一点,但它一直困扰着我一段时间,而且我一直无法找到解释这一点的资源。

    private static void BFS_UpdateAllWords(Node Root, string testword, string updatevalue)
    {
        Queue<Node> bfs_queue = new Queue<Node>();
        bfs_queue.Enqueue(Root);

        while (bfs_queue.Count > 0)
        {
            var deque = bfs_queue.Dequeue();

            foreach (string childKey in deque.Children.Keys)
            { // Update all child nodes at the key
                if (deque.Children[childKey].Word.Equals(testword))
                {
                    // This part right here for any time of Tree traversal
                    deque.Children[childKey].WordType = updatevalue;
                }
                bfs_queue.Enqueue(deque.Children[childKey]);
            }
        }
    }

【问题讨论】:

  • 我不确定我是否理解您的问题。你认为正在发生什么?为什么你认为它正在发生?应该发生的事情。

标签: c# search memory data-structures computer-science


【解决方案1】:

我认为您遇到的问题大致是按值传递与按引用传递的问题。当一个函数按值传递时,该函数的参数被复制,这样函数就有了自己的不同版本,调用者不会看到函数对参数所做的更改。但是,如果函数是通过引用传递的,则不会进行复制,并且如果函数对参数进行更改,调用者将看到所做的更改。

C# 和 Java 在这里有点有趣,因为它们总是按值传递(除非您明确告诉 C# 不这样做),但它们也“按值传递引用”。也就是说,当您向函数传递引用类型(如对象或类)时,函数接收到的是对它的引用的副本(而不是底层对象的深层副本)。这意味着底层对象仍然可以在函数内部进行更改,因为该函数有它自己的引用。

这样做的结果是,当您向 Enqueue 方法传递一个引用类型时,就像您的 Node 对象一样,存储在队列中的只是对位于队列外的相同底层对象的引用(副本)。也就是说,队列的元素不是树节点的深层副本:它们是对相同底层 Node 对象的引用。因此,当您将 Deque() 放入“deque”变量时,您只是创建了另一个别名,该别名引用了某个节点,否则您可能可以直接从根节点遍历该节点。这样,当您修改“deque”节点的属性时,您会直接修改某个 Node 对象的属性,因为它存在于 Root 节点下的树中——不是该对象在内存中具有自己地址的副本,而是相同的底层对象。

这就是为什么当双端队列被垃圾回收时,更改仍然存在:双端队列只包含对根树中已经存在的节点的引用的副本。您的程序无需弄清楚就可以使您通过双端队列所做的更改也影响根树中的节点。因为 deque 包含对相同底层节点的引用,所以通过它所做的更改已经直接修改了这些节点,因此在 deque 超出范围后,更改自然会持续存在。

【讨论】:

  • 谢谢!这正是我想要的!
猜你喜欢
  • 1970-01-01
  • 2019-08-28
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多