为什么这个链表添加方法有效?
why is this linked-list add method working?
我创建了这个方法来将一个数字添加到链表中,但我不太明白它为什么有效。
如果你看一下下面的代码,你会注意到我创建了一个名为“current”的变量,它设置了 this.head 的内容,直到那时一切正常,但我不明白为什么 this.head 正在更新当前变量的值,如果我没有告诉 Javascript 这样做的话。
这是我的代码,非常感谢你们能给我的帮助
class Node {
constructor(value, next_node = null) {
this.value = value;
this.next_node = next_node;
}
}
class LinkedList {
// setup head and tail
constructor() {
this.head = null;
this.length = 0;
}
add(number) {
let node = new Node(number)
if(this.head === null){
this.head = node;
} else {
let current = this.head;
while(current.next_node !== null){
current = current.next_node
}
current.next_node = node;
console.log(this.head)
}
this.length++
}
get(index) {
}
}
const ll = new LinkedList();
ll.add(2)
ll.add(3)
ll.add(5)
可视化过程可能会有所帮助:
使用 const ll = new LinkedList()
创建列表后,我们可以将情况表示为:
ll
↓
┌────────────┐
│ head: null │
│ length: 0 │
└────────────┘
现在我们执行ll.add(2)
,它使this
等同于ll
,然后我们执行let node = new Node(number)
。可以描述为:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐
│ head: null │ │ value: 2 │
│ length: 0 │ │ next_node: null │
└────────────┘ └─────────────────┘
if
条件为真,所以执行this.head = node
,最后this.length++
。对 add
的调用结束,因此 node
变量超出范围:
ll/this
↓
┌────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │
│ length: 1 │ │ next_node: null │
└────────────┘ └─────────────────┘
当ll.add(3)
被执行时,我们就进入了你问题的核心。再次执行 let node = new Node(number)
:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │
│ length: 1 │ │ next_node: null │ │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘
这次if
条件为假,我们执行let current = this.head
:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │
│ length: 1 │ │ next_node: null │ │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘
↑
current
由于while
条件为假,循环不迭代,我们执行current.next_node = node
和this.length++
:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │
│ length: 2 │ │ next_node: ──────── │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘
↑
current
这很关键:因为 current
引用与 this.head
相同的节点,无论您通过 this.head
还是通过 [=36= 查看节点的变化都是可见的]: 是同一个节点。
这个应该说清楚了。为了完成示例脚本,让我们也执行 ll.add(5)
。在 else
块中 while
循环的开始处,我们有:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │ │ value: 5 │
│ length: 2 │ │ next_node: ──────── │ next_node: null │ │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
↑
current
现在循环进行一次迭代,使 current
指向第二个节点实例:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │ │ value: 5 │
│ length: 2 │ │ next_node: ──────── │ next_node: null │ │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
↑
current
最后,current.next_node = node
和this.length++
被执行,之后变量node
和current
结束它们的生命:
ll
↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │ │ value: 5 │
│ length: 3 │ │ next_node: ──────── │ next_node: ──────── │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
这完成了列表并间接改变了 ll.head
引用的内容。
我创建了这个方法来将一个数字添加到链表中,但我不太明白它为什么有效。
如果你看一下下面的代码,你会注意到我创建了一个名为“current”的变量,它设置了 this.head 的内容,直到那时一切正常,但我不明白为什么 this.head 正在更新当前变量的值,如果我没有告诉 Javascript 这样做的话。
这是我的代码,非常感谢你们能给我的帮助
class Node {
constructor(value, next_node = null) {
this.value = value;
this.next_node = next_node;
}
}
class LinkedList {
// setup head and tail
constructor() {
this.head = null;
this.length = 0;
}
add(number) {
let node = new Node(number)
if(this.head === null){
this.head = node;
} else {
let current = this.head;
while(current.next_node !== null){
current = current.next_node
}
current.next_node = node;
console.log(this.head)
}
this.length++
}
get(index) {
}
}
const ll = new LinkedList();
ll.add(2)
ll.add(3)
ll.add(5)
可视化过程可能会有所帮助:
使用 const ll = new LinkedList()
创建列表后,我们可以将情况表示为:
ll
↓
┌────────────┐
│ head: null │
│ length: 0 │
└────────────┘
现在我们执行ll.add(2)
,它使this
等同于ll
,然后我们执行let node = new Node(number)
。可以描述为:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐
│ head: null │ │ value: 2 │
│ length: 0 │ │ next_node: null │
└────────────┘ └─────────────────┘
if
条件为真,所以执行this.head = node
,最后this.length++
。对 add
的调用结束,因此 node
变量超出范围:
ll/this
↓
┌────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │
│ length: 1 │ │ next_node: null │
└────────────┘ └─────────────────┘
当ll.add(3)
被执行时,我们就进入了你问题的核心。再次执行 let node = new Node(number)
:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │
│ length: 1 │ │ next_node: null │ │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘
这次if
条件为假,我们执行let current = this.head
:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │
│ length: 1 │ │ next_node: null │ │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘
↑
current
由于while
条件为假,循环不迭代,我们执行current.next_node = node
和this.length++
:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │
│ length: 2 │ │ next_node: ──────── │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘
↑
current
这很关键:因为 current
引用与 this.head
相同的节点,无论您通过 this.head
还是通过 [=36= 查看节点的变化都是可见的]: 是同一个节点。
这个应该说清楚了。为了完成示例脚本,让我们也执行 ll.add(5)
。在 else
块中 while
循环的开始处,我们有:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │ │ value: 5 │
│ length: 2 │ │ next_node: ──────── │ next_node: null │ │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
↑
current
现在循环进行一次迭代,使 current
指向第二个节点实例:
ll/this node
↓ ↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │ │ value: 5 │
│ length: 2 │ │ next_node: ──────── │ next_node: null │ │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
↑
current
最后,current.next_node = node
和this.length++
被执行,之后变量node
和current
结束它们的生命:
ll
↓
┌────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ head: ──────── │ value: 2 │ │ value: 3 │ │ value: 5 │
│ length: 3 │ │ next_node: ──────── │ next_node: ──────── │ next_node: null │
└────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
这完成了列表并间接改变了 ll.head
引用的内容。