我正在学习如何将节点添加到链表。正确的代码如下:
class NodeList {
constructor(head = null){
this.head = head
this.addLast = function (data) {
let node = new Node(data)
console.log(curr)
if (this.head === null) {
return this.head = node
} else{
let curr = this.head
while(curr.next){
curr = curr.next
}
curr.next = node
}
}
}
}
最初
我写的代码如下:
class NodeList {
constructor(head = null){
this.head = head
this.addLast = function (data) {
let node = new Node(data)
console.log(curr)
if (this.head === null) {
return this.head = node
} else{
let curr = this.head
while(curr.next){
curr = curr.next
}
curr.next = node
}
}
}
}
主要区别在于if语句。而不是
if(this.head === null) { return this.head = node}
我写的
let curr = this.head
if(curr === null) { return curr = node}
但是,代码不能工作。
如果我输入
let nodeList = new nodeListnodeList.addLast (2)
我期望得到head: Node {data: 2, next: null}。第一个代码实现了购买,但第二个代码没有。我不明白为什么会这样。两个代码看起来是一样的。有人能开导我吗?
也许你可以从这里阅读链接列表源代码https://github.com/samavati/tsds
区别在于:
curr
是一个变量。this.head
是一个对象的属性。
如果你赋值给curr
,你将在查看变量时看到效果,而不是其他地方。如果分配给this.head
,则修改属于对象的属性。所以这个改变了一个对象。对curr
的赋值不能改变对象。它只是给一个变量赋值。
如果赋值给一个变量会改变一个对象(在本例中是列表),那么想象一下curr = curr.next
语句会带来什么破坏(在else
块中)…然而,您似乎确实明白,这条语句并没有改变列表,它只是允许带着一个变量在列表中遍历。因此,没有理由认为curr = node
会改变列表。
它可能有助于在第一个代码块中可视化过程。假设我们在一个空列表上调用addLast(1)
。当我们到达if
块时,我们可以这样描绘状态:
this node
│ │
▼ ▼
┌────────────┐ ┌────────────┐
│ head: null │ │ val: 1 │
└────────────┘ │ next: None │
└────────────┘
所以我们实际上有两个变量:this
和node
。然后执行curr = this.head
:
this curr node
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐
│ head: null │ │ val: 1 │
└────────────┘ │ next: None │
└────────────┘
那么你的代码建议做curr = node
。看看发生了什么:
this curr node
│ └────────────┐ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐
│ head: null │ │ val: 1 │
└────────────┘ │ next: None │
└────────────┘
如果你做curr.next = node
,你会得到你需要的突变:
this curr node
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐
│ head: ────────► │ val: 1 │
└────────────┘ │ next: None │
└────────────┘
希望这能澄清。