那么让我们逐行看看Linked List 类的AddAtLast(object data) 方法中发生了什么
Node newNode = new Node();
创建一个新的节点,这是AddAtLast方法的人生目标
newNode.Value = data;
给节点分配一些数据
current.Next = newNode;
将创建的newNode 分配给Current。这是 Linked List
的
Linked 部分
current = newNode;
覆盖Current(这一定很奇怪);稍后我会详细解释。
Count++
增加Linked List 的Count,很高兴知道列表的大小,而不必遍历其所有元素。这只是一种始终知道计数的简便方法。
你必须记住的第一件事
在 C#(和许多其他语言)中,对象/类是 Reference Type。当您创建 Current(或任何其他对象/类)时,您正在做两件事。
- 保留内存的物理部分并用新对象填充它
- 创建对该内存的引用(又名地址,又名指针)。可以将地址想象成 Post-It-Note 来表示您家中某处存在的东西。
当您覆盖引用时,实际上并不会破坏内存,就像您在便利贴上潦草地写下地址并写下其他内容一样。你的鞋子还在柜子里。 .Net 中唯一的例外是,如果没有更多对您的对象/类的引用,Garbage Collector(您的妈妈)会来清理并丢弃它。
通过调用current = newNode;,似乎我们只是丢失了覆盖它,并且丢失了对该节点的所有引用(我们上次跟踪),但我们没有。
要记住的第二件事
发明 Linked List 的 Clever-Clogs 知道我们必须以某种方式跟踪项目,因此他们设想在添加 Node 时,在某个其他节点的某个地方需要有一个链接到它。
这就是这行代码 (current.Next = newNode) 的全部内容。确保它在列表中实际链接。是的,所以我们重写了它,但我们现在知道,当其他人引用时,Node它不会被清理。此外,如果我们想再次找到它,我们所要做的就是找到第一个 Node 并遍历链接。
另一种思考方式
把Current想象成一个桶,在那个桶里有一个Node,在那个Node上有一张纸叫做next。
- 有人递给你一个新的节点。
- 您特意将这个新节点的名称(有人给我们的)写在您当前在存储桶中的 Node 上(每个节点都有的
Next/Link Post-It-Note)李>
- 您将桶倒在地板上,然后将新的节点放入桶中。
但是你必须记住,你提示的 Node 仍然在某个地方(事实上,可能还有另一个 Node 上面也有它的名字,就像你写你的新 Nodes it 上的新名称)。虽然,我们无法轻松访问它们,但如果我们遍历 Linkages
,它们仍然存在
本质上,这就是链表的工作方式,它只是一堆节点,上面写着其他节点名称。
我们使用封装此逻辑的类中的Current/Temp 和First/Head(Buckets)等工具来跟踪列表。有时我们有一个Count,以便更容易知道我们正在跟踪多少个节点。虽然确实,Linked List 中最重要的部分是 First/Head 存储桶。没有它,我们无法遍历列表。
Current/Temp在你原来的方法中只是让我们很容易找到最后一个节点,所以你不必遍历列表来找到它
示例