skip to Main Content

I do understand what happens there. But I want to visualize the whole steps.

Let me clarify:

list and head are stored across the stack with reference and pointed to the same object. okay.

when it performs list.next = { val: c, next: null}, it updates the head like { val: 0, next: { val: 1, next: null }}.

Then list = list.next happens means now the list will be { val: 1, next: null }.

Consecutively next, the head is updated to { val: 0, next: { val: 1, next: {val: 2, next: null}}}.

At this point,

  1. how the things happen?
  2. is there any reference change?
  3. Why head variable is indicating the last node?
let head = { val: 0, next: null };

let list = head;

const arr = [1, 2, 3, 4];

for (let c of arr) {
  list.next = { val: c, next: null };
  list = list.next;
}

console.log(head);
  1. how the things happen?
  2. is there any reference change?
  3. Why head variable is indicating the last node?

2

Answers


  1. Not 100% sure what your question is but let me give an explanation of whats happening:
    In js all objects are passed by reference similar to python(guessing by the loop you seem to come from python). Which means the first line creates an object in memory and assigns its address(reference) to ‘head’.
    Now when you do list = head, both list and head point to the same object. When you do list.next=something, it assigns a new value to the next property of the same object. But both list and head still point to the same parent base object. Only now it has more children.
    Next you do list=list.next, at this point the list variable starts pointing to the object held in the next property. Please note that now head and list are pointing to different things. Head still points to the very first parent object. While list keeps pointing to the embeded child object(linkedlist in js is just nested objects). In js ‘objects’ are just plain dicts in python but have a much wider usage.
    Finally when the loop ends the list will be pointing to the last child while head keeps pointing to the base parent object. You can confirm this by just pasting the code in the console of the browser

    enter image description here

    Login or Signup to reply.
  2. The head is not getting updated to { val: 0, next: { val: 1, next: null }}. The head reference never changes, and keeps referencing the same node. To make head point to a different node, you’d have to make an assignment to head, but that never happens after the first and only assignment to it.

    On the other hand, list does get assigned new references, which is to the last node that was created.

    I want to visualize the whole steps.

    OK. After the first two statements, where head and list are assigned, we have the following state:

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

    The two variables head and list reference the same node.

    In the first iteration of the loop, c is 1, and the following property assignment is executed — this is a mutation of the node that was created above:

    list.next = { val: c, next: null };
    

    The effect is as follows:

     head  list
      ↓     ↓
    ┌────────────┐   ┌────────────┐
    │ value:   0 │   │ value:   1 │
    │ next: ────────►│ next: null │
    └────────────┘   └────────────┘
    

    The next statement is crucial: the variable list gets a new reference. This is not a mutation, but a variable assignment:

    list = list.next;
    

    And so we get this:

     head              list
      ↓                 ↓
    ┌────────────┐   ┌────────────┐
    │ value:   0 │   │ value:   1 │
    │ next: ────────►│ next: null │
    └────────────┘   └────────────┘
    

    Notice how head and list no longer reference the same node!

    Let’s do one more iteration of the loop, with c equal to 2. First:

    list.next = { val: c, next: null };
    

    …leads to:

     head              list
      ↓                 ↓
    ┌────────────┐   ┌────────────┐   ┌────────────┐
    │ value:   0 │   │ value:   1 │   │ value:   2 │
    │ next: ────────►│ next: ────────►│ next: null │
    └────────────┘   └────────────┘   └────────────┘
    

    And again list = list.next; will assign only to the list variable, so we get:

     head                              list
      ↓                                 ↓
    ┌────────────┐   ┌────────────┐   ┌────────────┐
    │ value:   0 │   │ value:   1 │   │ value:   2 │
    │ next: ────────►│ next: ────────►│ next: null │
    └────────────┘   └────────────┘   └────────────┘
    

    The invariant here is that head always references the first node of the list, and at the start (and end) of a loop’s iteration, list references the last node in the list.

    I hope this clarifies it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search