Home > Software engineering >  How does push method work on head Node in SinglyLinkedList
How does push method work on head Node in SinglyLinkedList

Time:07-29

I can't wrap my head around how does Head also changes whenever assigning a new Node to Tail. Do I miss something important about how Class works? Please explain in detail to me.

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

class SinglyLinkedList {
    constructor(){
        this.head = null
        this.tail = null
        this.length = 0
    }
    push(val){
        let newNode = new Node(val)
        if(!this.head){
            this.head = newNode // <-- this line
            this.tail = this.head
        }else{
            this.tail.next = newNode
            this.tail = newNode
        }
        this.length  
        return this
    }
}
 let list = new SinglyLinkedList()
 slist.push(1)
 slist.push(2)
 slist.push(3)

 console.log(JSON.stringify(list))
//output {"head":{"val":1,"next":{"val":2,"next":
// {"val":3,"next":null}}},"tail":{"val":3,"next":null},"length":3}

Doesn't Head only get the first Node object?

CodePudding user response:

This is the case when the list is empty and the first item is added. - if(!this.head)

CodePudding user response:

It might help to visualise this.

When let list = new SinglyLinkedList() has executed we can picture the state like this:

slist
  │
  ▼
┌────────────┐
│ head: null │
│ tail: null │
│ length: 0  │
└────────────┘           

Now let's see what happens when slist.push(1) is called. While executing that method, this will be slist. First newNode is created as new Node(val):

this
slist             newNode
  │                 │
  ▼                 ▼
┌────────────┐    ┌────────────┐
│ head: null │    │ val:  1    │
│ tail: null │    │ next: null │
│ length: 0  │    └────────────┘
└────────────┘

As this.head is null, !this.head is a truthy expression, so the if block gets executed. this.head = newNode results in this state:

this
slist             newNode
  │                 │
  ▼                 ▼
┌────────────┐    ┌────────────┐
│ head: ────────► │ val:  1    │
│ tail: null │    │ next: null │
│ length: 0  │    └────────────┘
└────────────┘

After this.tail = this.head executes, we get this:

this
slist             newNode
  │                 │
  ▼                 ▼
┌────────────┐    ┌────────────┐
│ head: ────────► │ val:  1    │
│ tail: ────────► │ next: null │
│ length: 0  │    └────────────┘
└────────────┘

And finally, the length property is incremented. return this is executed, but that return value is not used by the caller. So the caller sees this:

slist (returned)
  │
  ▼
┌────────────┐    ┌────────────┐
│ head: ────────► │ val:  1    │
│ tail: ────────► │ next: null │
│ length: 1  │    └────────────┘
└────────────┘

With the next call of push, we again get a newNode:

this
slist                               newNode
  │                                   │
  ▼                                   ▼
┌────────────┐    ┌────────────┐    ┌────────────┐
│ head: ────────► │ val:  1    │    │ val:  2    │
│ tail: ────────► │ next: null │    │ next: null │
│ length: 1  │    └────────────┘    └────────────┘
└────────────┘

This time head is not null and so we get into the else block. There we execute this.tail.next = newNode:

this
slist                               newNode
  │                                   │
  ▼                                   ▼
┌────────────┐    ┌────────────┐    ┌────────────┐
│ head: ────────► │ val:  1    │    │ val:  2    │
│ tail: ────────► │ next: ────────► │ next: null │
│ length: 1  │    └────────────┘    └────────────┘
└────────────┘

And finally this.tail = newNode and this.length are executed:

this
slist                               newNode
  │                                   │
  ▼                                   ▼
┌────────────┐    ┌────────────┐    ┌────────────┐
│ head: ────────► │ val:  1    │    │ val:  2    │
│ tail: ───────┐  │ next: ────────► │ next: null │
│ length: 2  │ │  └────────────┘    └────────────┘
└────────────┘ │                      ▲
               └──────────────────────┘

Repeat this process for the call of slist.push(3) and the caller ends up with:

slist
  │
  ▼
┌────────────┐    ┌────────────┐    ┌────────────┐    ┌────────────┐
│ head: ────────► │ val:  1    │    │ val:  2    │    │ val:  3    │
│ tail: ───────┐  │ next: ────────► │ next: ────────► │ next: null │
│ length: 2  │ │  └────────────┘    └────────────┘    └────────────┘
└────────────┘ │                                         ▲
               └─────────────────────────────────────────┘
  • Related