代码之家  ›  专栏  ›  技术社区  ›  andgarzonmal

为什么这个链表添加方法有效?

  •  0
  • andgarzonmal  · 技术社区  · 2 年前

    我创建了这个方法来将数字添加到链表中,但我真的不明白为什么它有效。

    如果你看一下下面的代码,你会注意到我创建了一个名为“current”的变量,它是用this.head的内容设置的,在那之前一切都很完美,但我不明白如果我没有告诉Javascript,为什么this.head会用当前变量的值更新。

    这是我的密码,我真的很感激你们能给我的帮助

    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)
    0 回复  |  直到 2 年前
        1
  •  0
  •   trincot    2 年前

    这可能有助于将过程可视化:

    使用创建列表后 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=新节点(数量) 执行:

     ll/this                                  node
      ↓                                        ↓
    ┌────────────┐    ┌─────────────────┐    ┌─────────────────┐
    │ head: ────────🞂 │ value: 2        │    │ value: 3        │
    │ length: 1  │    │ next_node: null │    │ next_node: null │
    └────────────┘    └─────────────────┘    └─────────────────┘
    

    这一次 如果 条件为false,我们执行 let current = this.head :

     ll/this                                  node
      ↓                                        ↓
    ┌────────────┐    ┌─────────────────┐    ┌─────────────────┐
    │ head: ────────🞂 │ value: 2        │    │ value: 3        │
    │ length: 1  │    │ next_node: null │    │ next_node: null │
    └────────────┘    └─────────────────┘    └─────────────────┘
                        ↑
                       current
    

    作为 while 条件为false,循环不迭代,我们执行 current.next_node = node 这个长度++ :

     ll/this                                  node
      ↓                                        ↓
    ┌────────────┐    ┌─────────────────┐    ┌─────────────────┐
    │ head: ────────🞂 │ value: 2        │    │ value: 3        │
    │ length: 2  │    │ next_node: ────────🞂 │ next_node: null │
    └────────────┘    └─────────────────┘    └─────────────────┘
                        ↑
                       current
    

    这一点至关重要: current 引用了与相同的节点 this.head ,节点的突变是可见的,无论你通过 这个头 或通过 现在的 :它是同一个节点。

    这应该说明问题。为了完成示例脚本,我们还执行 ll.add(5) 。在开始时 虽然 中的循环 else 块,我们有这样的:

     ll/this                                                         node
      ↓                                                               ↓
    ┌────────────┐    ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
    │ head: ────────🞂 │ value: 2        │    │ value: 3        │    │ value: 5        │
    │ length: 2  │    │ next_node: ────────🞂 │ next_node: null │    │ next_node: null │
    └────────────┘    └─────────────────┘    └─────────────────┘    └─────────────────┘
                        ↑
                       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=节点 这个长度++ 执行,之后变量 节点 现在的 结束他们的生命:

     ll
      ↓
    ┌────────────┐    ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
    │ head: ────────🞂 │ value: 2        │    │ value: 3        │    │ value: 5        │
    │ length: 3  │    │ next_node: ────────🞂 │ next_node: ────────🞂 │ next_node: null │
    └────────────┘    └─────────────────┘    └─────────────────┘    └─────────────────┘
    

    这就完成了列表,并间接地改变了什么 ll.head 正在引用。