简体   繁体   English

Javascript 中的变量更新

[英]Variable Update in Javascript

I am learning about Linked Lists and was looking at this solution for a problem:我正在学习链接列表,并正在寻找这个解决方案来解决问题:

   /**
   * Definition for singly-linked list.
   * function ListNode(val, next) {
   *     this.val = (val===undefined ? 0 : val)
   *     this.next = (next===undefined ? null : next)
   * }
   */
   /**
   * @param {ListNode} list1
   * @param {ListNode} list2
   * @return {ListNode}
   */
   var mergeTwoLists = function(list1, list2) {
      let list = new ListNode();
      let head = list;
      console.log("first", head);
      while (list1 && list2) {
          if (list1.val <= list2.val) {
              list.next = list1;
              console.log("second", head);
              list1 = list1.next;
          } else {
              list.next = list2;
              list2 = list2.next;
          }
          list = list.next;
      }
      console.log("third", head, list);
      return head.next;
   };

There is one thing I can not understand.有一件事我无法理解。 So, the "head" is set to track the "list".所以,“头”被设置为跟踪“列表”。 How come in the end the they have different values?他们到底怎么会有不同的价值观?

At first, "head" store the first node address.首先,“head”存储第一个节点地址。 As "list" move along the linked list by passing different node address to "list", the result is they are different at the end.当“list”通过将不同的节点地址传递给“list”来沿着链表移动时,结果是它们最终不同。 The "head" or "list" are just an address container, so they are not expected to be the same all the time. “头”或“列表”只是一个地址容器,因此它们不会一直相同。 If they store the same address, they the same.如果它们存储相同的地址,则它们相同。

let head = list;

In the above statement, the variable head holds the current value of the list and is not the reference to the list.在上面的语句中,变量 head 保存了列表的当前值,并不是对列表的引用。

while (list1 && list2) {
      if (list1.val <= list2.val) {
          list.next = list1;
          console.log("second", head);
          list1 = list1.next;
      } else {
          list.next = list2;
          list2 = list2.next;
      }
      list = list.next;
  }

In the above loop, on every iteration the value of the list changes, it will not impact the value of the head.在上面的循环中,每次迭代列表的值都会改变,它不会影响头部的值。

So, in the end, since head holds the initial address it prints the entire list of values, and list prints the current value of the list (the last node).因此,最后,由于head保存初始地址,它打印整个值列表,并且list打印列表的当前值(最后一个节点)。

See above image见上图在此处输入图像描述

here head -> [5, 7, 2, 15] list -> [15]这里头 -> [5, 7, 2, 15] 列表 -> [15]

So, the "head" is set to track the "list".所以,“头”被设置为跟踪“列表”。 How come in the end the they have different values?他们到底怎么会有不同的价值观?

The reason is that head never is assigned anything else after its first initialisation, while list is assigned something else in the loop.原因是head在第一次初始化后从未被分配任何其他内容,而list在循环中分配了其他内容。 list initially is referencing the same (dummy) node as head , but then later starts referencing different nodes by doing list = list.next repeatedly. list最初引用与head相同的(虚拟)节点,但后来通过重复执行list = list.next开始引用不同的节点。

It may help to visualise this.这可能有助于形象化。 Let's say we merge two lists with values 1, 4 and 2, 3 respectively:假设我们合并两个列表,其值分别为 1, 4 和 2, 3:

First we have the initialisation happening.首先我们进行初始化。 Just before the loop starts, we have this siutation:就在循环开始之前,我们有这种情况:

head list
  ↓   ↓
┌───────────┐
│ val:  0   │
│ next:null │
└───────────┘

list1
  ↓
┌───────────┐   ┌───────────┐
│ val:  1   │   │ val:  4   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘

┌───────────┐   ┌───────────┐
│ val:  2   │   │ val:  3   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘
  ↑
list2

In the first iteration of the loop, the first if condition is true, and so list.next = list1 gets executed.在循环的第一次迭代中,第一个if条件为真,因此list.next = list1被执行。 This leads to the following:这导致以下情况:

head list
  ↓   ↓
┌───────────┐
│ val:  0   │
│ next: ─┐  │
└────────│──┘
         │
list1    │ 
  ↓      ▼
┌───────────┐   ┌───────────┐
│ val:  1   │   │ val:  4   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘

┌───────────┐   ┌───────────┐
│ val:  2   │   │ val:  3   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘
  ↑
list2

The next statement assigns a different node reference to list1 with list1 = list1.next :下一条语句使用list1 = list1.nextlist1分配不同的节点引用:

head list
  ↓   ↓
┌───────────┐
│ val:  0   │
│ next: ─┐  │
└────────│──┘
         │
         │      list1
         ▼        ↓
┌───────────┐   ┌───────────┐
│ val:  1   │   │ val:  4   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘

┌───────────┐   ┌───────────┐
│ val:  2   │   │ val:  3   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘
  ↑
list2

The last statement in the first iteration of the loop, moves the list reference, with list = list.next , which means head and list no longer reference the same node;循环第一次迭代中的最后一条语句,移动list引用,使用list = list.next ,这意味着headlist不再引用同一个节点; and they will never be the same reference again:他们将永远不再是相同的参考:

head
  ↓
┌───────────┐
│ val:  0   │
│ next: ─┐  │
└────────│──┘
         │
list     │      list1
  ↓      ▼        ↓
┌───────────┐   ┌───────────┐
│ val:  1   │   │ val:  4   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘

┌───────────┐   ┌───────────┐
│ val:  2   │   │ val:  3   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘
  ↑
list2

In the second iteration of the loop, we get into the else block, and there we set list.next = list2 :在循环的第二次迭代中,我们进入 else 块,在那里我们设置list.next = list2

head
  ↓
┌───────────┐
│ val:  0   │
│ next: ─┐  │
└────────│──┘
         │
list     │      list1
  ↓      ▼        ↓
┌───────────┐   ┌───────────┐
│ val:  1   │   │ val:  4   │
│ next: ─┐  │   │ next:null │
└────────│──┘   └───────────┘
         ▼
┌───────────┐   ┌───────────┐
│ val:  2   │   │ val:  3   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘
  ↑
list2

Then list1 = list1.next will lead to:那么list1 = list1.next将导致:

head
  ↓
┌───────────┐
│ val:  0   │
│ next: ─┐  │
└────────│──┘
         │
list     │      list1
  ↓      ▼        ↓
┌───────────┐   ┌───────────┐
│ val:  1   │   │ val:  4   │
│ next: ─┐  │   │ next:null │
└────────│──┘   └───────────┘
         ▼
┌───────────┐   ┌───────────┐
│ val:  2   │   │ val:  3   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘
                  ↑
                 list2

And again, the final statement of this second iteration, will move list :同样,第二次迭代的最后一条语句将移动list

head
  ↓
┌───────────┐
│ val:  0   │
│ next: ─┐  │
└────────│──┘
         │
         │      list1
         ▼        ↓
┌───────────┐   ┌───────────┐
│ val:  1   │   │ val:  4   │
│ next: ─┐  │   │ next:null │
└────────│──┘   └───────────┘
         ▼
┌───────────┐   ┌───────────┐
│ val:  2   │   │ val:  3   │
│ next: ──────► │ next:null │
└───────────┘   └───────────┘
  ↑               ↑
list            list2

And so the process continues,... Never is head moving, but list is.所以这个过程继续,......从来没有动过head ,但list是。 When the loop exits, the situation will be this:当循环退出时,情况将是这样的:

head
  ↓
┌───────────┐
│ val:  0   │
│ next: ─┐  │
└────────│──┘
         │
         │                 list1 == null
         ▼
┌───────────┐   ┌───────────┐
│ val:  1   │   │ val:  4   │
│ next: ─┐  │   │ next:null │
└────────│──┘   └───────────┘
         ▼                ▲
┌───────────┐   ┌─────────│─┐
│ val:  2   │   │ val:  3 │ │
│ next: ──────► │ next: ──┘ │
└───────────┘   └───────────┘
                  ↑        
                list       list2 == null

The return value is head.next , which indeed is the reference to the first node (with value 1) of the merged list.返回值是head.next ,它确实是对合并列表的第一个节点(值为 1)的引用。

I hope this clarified it.我希望这能澄清它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM