【问题标题】:Linked List Pointers Javascript, append method链表指针 Javascript,追加方法
【发布时间】:2020-08-21 14:15:21
【问题描述】:

我认为这段代码可以很好地创建一个链表并附加到它, 但我不明白下面我评论它的一小段代码请帮忙。

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class LinkedList {
  constructor(value) {
    this.head = new Node(value);
    this.tail = this.head;
    this.length = 1;
  }
  append(value) {
    const newNode = new Node(value);
    // how come that we did not even mention this.head and it keeps adding to it??
    this.tail.next = newNode; //<<<<< can not figure this one
    this.tail = newNode;
    this.length++;

    return this;
  }
}

//test code
let myLinkedList = new LinkedList(10);

myLinkedList.append(5);
myLinkedList.append(16);
myLinkedList.append(14);
console.log(myLinkedList);

我试图理解的内容>>>

    // instantiation
p = { a: 1, b: null };
c = p;

// what happens when i call append
node = { a: 2, b: null };
c.b = node;
console.log(p);
c = node;

node1 = { a: 3, b: null };
c.b = node1;
console.log(p);
c = node1;

node2 = { a: 4, b: null };
c.b = node2;
console.log(p);
c = node2;

我想知道c 如何准确访问p 对象中的最后一个b 属性, 每个 b 都有它自己的内存地址还是因为c 包含a: 4 所以当我说c.b 它访问b 与它有a: 4

【问题讨论】:

  • 因为在构造函数中有这个语句this.tail = this.head;
  • 是的,我想过但还是不明白,你能解释一下吗
  • 我的意思是当我们改变 this.tail.next 它改变 this.head 但是,当我们改变 this.tail this.head 不响应?怎么样?
  • LinkedList 的新实例被创建时,this.tail 是对this.head 的引用(两个变量都指向同一个Node),那么,每次调用append , this.tail 改为指向最新创建的Node
  • 感谢您的帮助,感谢您的帮助,我添加了一个可以更好地证明我的困惑的部分,请您检查一下!

标签: javascript data-structures linked-list


【解决方案1】:

答案在于 JavaScript 工作原理的内存管理方法,

让我给你看一个例子,假设我们有一个类,

class Wait{
    constructor(name){
        this.name = name
        this.next = null
    }
}

现在这是我们期望在 LinkedLists 中使用 Append 方法的操作

示例 1>

let wait = new Wait('john')
let wait1 = new Wait('doe')
let wait2 = new Wait('foo')
let wait3 = new Wait('bar')
wait.next = wait1
wait1.next = wait2
wait2.next = wait3
console.log(JSON.stringify(wait))

// 输出:

{"name":"john","next":{"name":"doe","next":{"name":"foo","next":{"name":"bar","next":null}}}}

这里的waitwait1wait2wait3 是Javascript 引用对象,因此它们中的每一个都单独存储在堆栈内存中,但它们也由于分配而相互指向(=)。

所以对于一个实例来说,wait2 本身就是堆栈中的一个引用对象,但是一旦您执行wait1.next = wait2,后者现在指向前一个对象。

所以你基本上形成了一个引用对象链,你没有修改任何对象地址,你只是连接它们的指针。

一个有趣的观察是,即使你没有改变wait 中的任何东西,它的值也会随着每个next 而变化,这是因为 JavaScript 中的引用对象基本上是堆栈内存中的指针,在这里我们不断添加指向其后续引用的指针,wait 的值不断变化。

话虽如此,让我来看看它在 LinkedList 类中的工作原理,

考虑到上述情况,

示例 2>

 class VaccinationLine{
    constructor(){
        this.watingList = null 
        this.reference = null 
    }
    add(name){  
        let member = new Wait(name)
        if(this.watingList == null){
            this.watingList = member
            this.reference = member
        }else{
            this.reference.next = member
            this.reference = member //or = this.reference.next, both are same
            
        }
        return this.watingList
    }
}

let waitlist = new VaccinationLine()
waitlist.add('john')
waitlist.add('doe')
waitlist.add('foo')
waitlist.add('bar')
console.log(JSON.stringify(waitlist))

//输出

{"watingList":{"name":"john","next":{"name":"doe","next":{"name":"foo","next":{"name":"bar","next":null}}}},"reference":{"name":"bar","next":null}}

在上面的代码中,当你做let member = new Wait(name)时,它会在栈内存中创建一个引用对象,并将内容存储在堆中。

现在它们最初都指向同一个 member 对象,但随着我们继续循环,我们只更改 this.reference,就像我们在第一个示例中创建一个链wait1,wait2 等,如示例 1 的代码输出所示(即,当我们将对象链添加到对象链时,wait 的值也会不断变化)。

以类似的方式,因为this.waitingList 是我们行中的第一个对象引用,随着我们不断将对象添加到链中后续this.reference 对象的next 属性,this.waitingList 的值不断变化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 2018-03-28
    相关资源
    最近更新 更多