JavaScript中带尾的LinkedList push方法

问题描述

我尝试了解push()方法如何在JS中使用尾部。这是代码

class Node {
    constructor(val) {
      this.val = val;
      this.next = null;
    }
  }
  class SinglyLinkedList {
    constructor() {
      this.length = 0;
      this.head = null;
      this.tail = null;
    }
    push(val) {
      const newNode = new Node(val)
      if (this.head===null) { // happens only once
        this.head = newNode;
        this.tail = this.head;
      } else {
        this.tail.next = newNode;   // this.a.next = b node???
        this.tail = newNode;
      }
      this.length++
    }

具体来说,我不了解else方法内的push()部分。如果我们说nexthead中的每个this.tail.next = newNode都如何分配一个新节点?头尾之间的关系在哪里?如何说this.tail.next = newNode,才能访问列表的head属性?当我运行此代码时,它可以正确正确地工作,并且使我感到困惑。

const myList = new SinglyLinkedList();
  myList.push("111");
  myList.push("222");
  myList.push("333");
  console.log(myList);

输出

SinglyLinkedList {
  length: 3,head: Node { val: '111',next: Node { val: '222',next: [Node] } },tail: Node { val: '333',next: null } }

解决方法

如果我们说this.tail.next = newNode,next中的每个head都将被分配一个新节点?头和尾之间的关系在哪里,通过说this.tail.next = newNode,我们如何访问列表的head属性?

让我们回到空白列表。第一次添加节点时,我们进入if块,其中headtail都将引用 same 新节点。这意味着从那一刻起,您在tail中进行的任何更改都将对head进行更改,因为它们引用的是同一对象。

现在执行第二个push,我们进入else块。在那里,我们将新节点分配给next的{​​{1}}属性。但是由于这是tail所指的同一对象,因此我们实际上在这里设置了head!这仅发生在第二个head.next上,因为在此分配之后,push被分配了一个新的引用(tail),因此从nexthead开始指代不同的节点。

以图形方式:

tail之后:

push('111')

head ↓ 111 ↑ tail 之后push('222')之后:

this.tail.next = newNode;

...在同一次推送期间head ↓ 111 → 222 ↑ tail 之后:

this.tail = newNode;

head ↓ 111 → 222 ↑ tail 之后push('333')之后:

this.tail.next = newNode;

...在同一次推送期间head ↓ 111 → 222 → 333 ↑ tail 之后:

this.tail = newNode;