javascript - 为什么 this.tail 在我的 Linkedlist 类中更改 this.head 的属性?
问题描述
考虑一个模仿 Linkedlist 数据结构的 LinkedList 类,如下所示:
class LinkedList {
constructor(value) {
this.head = {
value: value,
next: null
};
this.tail = this.head;
this.length = 1;
}
append(value) {
const newNode = {
value: value,
next: null
}
this.tail.next = newNode; // why does this change head.next ?
this.tail = newNode;
this.length++;
return this;
}
}
let myLinkedList = new LinkedList(10);
myLinkedList.append(5);
日志输出
LinkedList {
head: { value: 10, next: { value: 5, next: null } },
tail: { value: 5, next: null },
length: 2
}
我看到这this.tail.next
也会改变tail的下一个属性(然后this.tail = newNode
将tail重新分配给newNode)。我在这里不明白的是为什么this.tail.next
还要更改 this.head 的下一个属性?
此外,当将另一个数字附加到 listmyLinkedList.append(16)
时,它会不断更新 head 的 next 属性,如下所示:
LinkedList {
head: { value: 10, next: { value: 5, next: [Object] } },
tail: { value: 16, next: null },
length: 3
}
也许一个可能的原因与我定义的构造函数有关this.tail = this.head
?但我不太确定,因为这只是从头到尾分配值。
总结一下,我的问题是为什么会this.tail.next = newNode
改变头部的下一个属性?另外,当附加另一个值时,为什么它会改变 head.next.next 等等?
解决方案
当构造函数运行this.tail
并this.head
引用同一个对象时,您所做的任何分配this.tail.next
都是可见的this.head
,因为这实际上是对正在变异的同一个对象的引用。
这可能有助于形象化。一旦构造函数运行,我们就会遇到这种情况:
this.head
↓
┌───────────┐
│ value: 10 │
│ next: null│
└───────────┘
↑
this.tail
然后append(5)
将首先创建一个新节点:
this.head newNode
↓ ↓
┌───────────┐ ┌───────────┐
│ value: 10 │ │ value: 5 │
│ next:null │ │ next:null │
└───────────┘ └───────────┘
↑
this.tail
然后this.tail.next = newNode;
执行,这是next
对第一个对象中该属性的修改:
this.head newNode
↓ ↓
┌───────────┐ ┌───────────┐
│ value: 10 │ │ value: 5 │
│ next: ———————→ │ next:null │
└───────────┘ └───────────┘
↑
this.tail
所以事实上,这也改变this.head.next
了......因为它只是相同的属性。
然后this.tail = newNode;
执行:
this.head newNode
↓ ↓
┌───────────┐ ┌───────────┐
│ value: 10 │ │ value: 5 │
│ next: ———————→ │ next:null │
└───────────┘ └───────────┘
↑
this.tail
下次append
调用时,第二个next
对象的属性会更新,所以我们得到:
this.head newNode
↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 10 │ │ value: 5 │ │ value: 16 │
│ next: ———————→ │ next: ———————→ │ next:null │
└───────────┘ └───────────┘ └───────────┘
↑
this.tail
是的,这个变化也是可追溯的this.head
,因为……它是一个链表……所以它应该是可追溯的。由于每个next
属性都指向下一个节点,因此您可以找到从head
任何节点到任何节点的方式。
推荐阅读
- javascript - 如何在 create-react-app 中动态导入图像
- css - 如何使用带有 svg 标签的 svg 图像
- php - 使用 mysql 和 php 搜索和过滤数据
- javascript - 拼接/移除选中的数组元素会移除选中元素之后的其他元素
- c++ - 对“TESTCLASS::TESTCLASS()”的未定义引用
- angular - 测试静态函数的最佳方法是检查它是否是本月的第一个星期一(Typescript/Angular/Jasmin)
- python - 如何在对 Pandas 系列进行排序后保持相同的索引?
- php - PHP中json /数组中的回声变量
- python - 如何将“\r\n”替换为<br> python pandas
- neo4j - 使用 Neo4j 中的 CALL 函数进行子查询会因为“{”而引发错误