Skip to reading
WritingData structures & algorithms

Linked List

Vinayak Agrawal3 MIN READ · 5 INTERACTIVE FIGURES

A Linked List is a data structure that has nodes. Each node has two things : A value and the whereabouts of the next node

We have the “head” of the list which is the reference to the starting node of the list

Linked list’s nodes may/may not occupy consecutive memory locations. Unlike array the location occupancy in the memory is not strict in terms of order.

If the next node’s reference is ‘null’, it’s the end of the list

If head = null ; Empty linked list

FIG. 01Values, connected by referencesINTERACTIVE
headnullA12BvaluenextB16CvaluenextC18∅valuenext
head → A → B → C → null

Each box is a node. The value is data; next is a reference to another node. ∅ marks a null reference.

Arrows show references, not adjacent memory addresses. These nodes do not need to sit next to one another in memory.

In JS we represent a node with an object:

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

Lets transverse through a linked list :

An array we can directly lookup the value on a specific index, but in a linked list we can’t do that

To reach index k, we start from the head then move k spaces to get information about it

let current = head;
// current is used as a reference to the head so that we can use it as a moving pointer

for (let i = 0; i < k && current !== null; i++) {
  current = current.next;
}

The worst time complexity here is O(n)

FIG. 02You get there one link at a timeINTERACTIVE
0 LINKS FOLLOWED
headnullA12BvaluenextB16CvaluenextC18∅valuenext
current = A

current is at A. Follow next to move one node closer to index 2.

0 / 2

Index 0 takes no hops. Reaching index k takes k hops when that node exists; there is no direct indexed jump.

Inserting a node:

Lets say we want to add X between node A and node B

we transverse till A, then the important part is to save B before adding X after A

This is because we have B with reference to A (A.next = B)

So first X.next = A.next (pointing X to B)

and then A.next = X (pointing A to X)

It’s important to follow this order because if we point A to X directly, we’ll loose B and we can’t point X to B after that

This change takes a constant O(1) time but reaching A might take n cases, so overall time is O(n)

FIG. 03Connect the new node firstINTERACTIVE
INSERT X BETWEEN A AND B2 LINK CHANGES
headnullnullA12BvaluenextX14∅valuenextB16∅valuenext
A.next = B

We already have A. X is a separate new node; the list still follows A → B.

0 / 2

The search for A is already complete here. These two assignments take O(1); finding A from head can take O(n).

Deleting a node:

To remove B from a list of A—>B—>C—>null

We skip B and point A.next directly to C(A.next.next)

This gives us A—>C—>null

This unlinks B from the list but it wont erase it from memory. In Javascript, an object becomes eligible for garbage collection (memory management mechanism that frees up memory occupied by objects no longer in use) when nothing references it anymore

Again the pointer change takes O(1) but overall finding A and operating takes O(n) in the worst case.

FIG. 04Change the route around a nodeINTERACTIVE
REMOVE B FROM THE LIST1 LINK CHANGE
headnullA12BvaluenextB16CvaluenextC18∅valuenext
head → A → B → C → null

We already have the predecessor A. Its next node is B, and B.next is C.

0 / 1

An outgoing link from B to C does not keep B alive. B becomes eligible for garbage collection when it is unreachable from all live references.

A Cyclic Linked List:

A normal singly linked lists ends at null. A cyclic list connects the last node to one of the nodes in the list rather than ending at null

To find if a Linked List is cyclic, we use two pointers ‘slow’ and ‘fast’ we start both of them from start. We move ‘slow’ by one and ‘fast’ by two spaces. If the list contains a cycle, slow and fast will eventually meet at the same node. If fast reaches null, there is no cycle.

FIG. 05Two speeds reveal a loopINTERACTIVE
headA12BvaluenextB16CvaluenextC18Bvaluenextslow · 1fast · 2
slow = head; fast = head

Both pointers start at A. Sharing the starting node does not prove a cycle; move them first.

0 / 2

Each click plays one round: slow follows one link; fast follows two. S and F trace the arrows. Compare node identity only after the full round. Check fast and fast.next before moving.

How to Identify a Linked list problem:

The simplest give away is when a problem gives is a head node

Common problems are reversing the links, removing nodes, remove duplicates from sorted lists

END OF CHAPTER 02