Linked List Deletion Operations

Learn Linked List Deletion Operations with practical examples, explanations, best practices, and real-world coding techniques.

What Is Linked List Deletion?

Linked list deletion is the process of removing a node from a linked list and reconnecting the remaining nodes. Unlike an array, deleting a node from a linked list does not normally require shifting all following elements. Instead, the references between nodes are updated so that the removed node is no longer part of the list.

The exact deletion steps depend on the location of the node. Common operations include deleting the first node, deleting the last node, deleting a node by value, and deleting a node at a specific position.

The Basic Idea Behind Deletion

Consider a singly linked list containing three nodes:

10 → 20 → 30 → null

If the node containing 20 needs to be deleted, the node containing 10 should point directly to 30.

10 ─────────→ 30 → null

        20
        ↓
      removed

The key operation is therefore changing the next reference of the previous node.

Deleting the First Node

Deleting the first node is the simplest deletion operation in a singly linked list. The head simply moves to the second node.

Before:

head
 ↓
10 → 20 → 30 → null

After deleting 10:

head
 ↓
20 → 30 → null

In JavaScript, this can be implemented by assigning the current head's next node to head.

head = head.next;

Because no traversal is required, deleting the first node takes O(1) time.

Deleting the Last Node

Deleting the last node requires finding the node immediately before the last node in a singly linked list. That node's next reference must then be changed to null.

Before:

10 → 20 → 30 → null

After deleting 30:

10 → 20 → null

One way to find the previous node is to traverse until current.next.next is null.

let current = head;

while (current.next.next !== null) {
  current = current.next;
}

current.next = null;

Since the list may need to be traversed, deleting the last node takes O(n) time in a singly linked list when only the head is available.

Deleting a Node by Value

Deleting by value means searching for a node containing a particular value and then removing it from the list.

For example, consider:

10 → 20 → 30 → 40 → null

If 30 is deleted, the node containing 20 should point directly to 40.

10 → 20 → 40 → null

A typical implementation keeps track of both the current node and its previous node.

let current = head;
let previous = null;

while (current !== null && current.data !== 30) {
  previous = current;
  current = current.next;
}

if (current !== null) {
  previous.next = current.next;
}

The search can require visiting every node, so deletion by value takes O(n) time in the general case.

Deleting a Node at a Specific Position

Another common operation is deleting the node at a given position. If position 0 is requested, the head is removed. For other positions, traversal is used to reach the node immediately before the target.

For example, deleting position 2 from:

10 → 20 → 30 → 40 → null
               ↑
            position 2

produces:

10 → 20 → 40 → null

The important reference update is:

previous.next = current.next;

Complete JavaScript Implementation

The following implementation supports deleting the first node, last node, a node by value, and a node at a specific position.

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

class LinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
    this.size = 0;
  }

  insertAtEnd(data) {
    const newNode = new Node(data);

    if (this.head === null) {
      this.head = newNode;
      this.tail = newNode;
    } else {
      this.tail.next = newNode;
      this.tail = newNode;
    }

    this.size++;
  }

  deleteFirst() {
    if (this.head === null) {
      return;
    }

    this.head = this.head.next;
    this.size--;

    if (this.head === null) {
      this.tail = null;
    }
  }

  deleteLast() {
    if (this.head === null) {
      return;
    }

    if (this.head.next === null) {
      this.head = null;
      this.tail = null;
      this.size--;
      return;
    }

    let current = this.head;

    while (current.next.next !== null) {
      current = current.next;
    }

    current.next = null;
    this.tail = current;
    this.size--;
  }

  deleteByValue(value) {
    if (this.head === null) {
      return;
    }

    if (this.head.data === value) {
      this.deleteFirst();
      return;
    }

    let current = this.head;

    while (current.next !== null && current.next.data !== value) {
      current = current.next;
    }

    if (current.next === null) {
      return;
    }

    if (current.next === this.tail) {
      this.tail = current;
    }

    current.next = current.next.next;
    this.size--;
  }

  deleteAtPosition(position) {
    if (position < 0 || position >= this.size) {
      throw new Error('Invalid position');
    }

    if (position === 0) {
      this.deleteFirst();
      return;
    }

    let current = this.head;

    for (let i = 0; i < position - 1; i++) {
      current = current.next;
    }

    if (current.next === this.tail) {
      this.tail = current;
    }

    current.next = current.next.next;
    this.size--;
  }

  print() {
    const values = [];
    let current = this.head;

    while (current !== null) {
      values.push(current.data);
      current = current.next;
    }

    console.log(values.join(' → '));
  }
}

const list = new LinkedList();

list.insertAtEnd(10);
list.insertAtEnd(20);
list.insertAtEnd(30);
list.insertAtEnd(40);

list.deleteByValue(30);
list.deleteAtPosition(1);

list.print();

After the deletion operations, the list contains:

10 → 40

Deleting the Only Node

A list containing only one node is an important edge case. If that node is deleted, both head and tail must become null.

Before:

head
 ↓
10 → null
 ↑
tail

After deletion:

head = null
tail = null

Forgetting to update the tail can leave a stale reference to a node that is no longer part of the linked list.

Deleting the Head When a Tail Is Maintained

When a linked list stores both head and tail, deleting the head requires an additional check. If the deleted head was also the tail, the list becomes empty and both references must be cleared.

deleteFirst() {
  if (this.head === null) {
    return;
  }

  this.head = this.head.next;

  if (this.head === null) {
    this.tail = null;
  }
}

Deleting a Known Node

If the previous node is already known, deletion itself can be performed in constant time. The previous node simply skips the node being removed.

previous.next = current.next;

The reference change is O(1). However, if the previous node is not known, traversal may be required to find it, making the overall operation O(n).

Linked List Deletion Complexity

Deletion Operation Time Complexity Why?
First node O(1) Head moves to the next node
Last node O(n) Previous node must usually be found
By value O(n) The target may require a full traversal
At position O(n) Traversal may be required to reach the target
After known previous node O(1) Only a reference needs to be changed

Linked List Deletion vs Array Deletion

The main difference between linked list deletion and array deletion is how the remaining elements are connected after an item is removed. Arrays generally need elements after the deleted position to be shifted. A linked list can remove a node by changing references.

Factor Linked List Array
Delete from beginning O(1) Usually O(n)
Delete from middle O(1) after reaching the previous node Usually O(n)
Random access O(n) O(1)
Reference overhead Yes Generally lower

Common Linked List Deletion Mistakes

  • Trying to access head.next when the list is empty.
  • Forgetting to move the head when deleting the first node.
  • Forgetting to update the tail after deleting the last node.
  • Failing to handle a list containing only one node.
  • Updating the wrong reference and disconnecting part of the list.
  • Not checking whether the requested value or position exists.
  • Using an invalid position without validating it first.

A Safe Deletion Pattern

A reliable way to approach deletion is to identify the node before the target and then connect it to the node after the target.

Before:

previous → target → next

Delete target:

previous → next

This pattern is used repeatedly in linked list problems. Once the surrounding references are identified, the actual deletion usually requires only a small number of pointer changes.

Linked List Deletion in Interviews

Linked list deletion is a common interview topic because it tests reference manipulation, traversal, and edge-case handling. Problems may ask you to remove a node by value, delete the node at a position, remove duplicates, delete the middle node, or remove nodes that satisfy a condition.

Before writing the deletion logic, check whether the target can be the head, whether the list can be empty, whether the target can be the only node, and whether a tail reference needs to be updated.

Key Takeaways

  • Linked list deletion removes a node by updating references between neighboring nodes.
  • Deleting the first node takes O(1) time.
  • Deleting the last node in a singly linked list generally requires O(n) traversal.
  • Deleting by value may require searching the entire list.
  • Deleting at a specific position usually requires traversal.
  • If the previous node is already known, the reference change itself takes O(1) time.
  • Always handle empty lists, single-node lists, head deletion, and tail updates carefully.

Code Examples

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

let head = new Node(10);
head.next = new Node(20);
head.next.next = new Node(30);

head = head.next;

console.log(head.data); // 20
    
function deleteByValue(head, value) {
  if (head === null) {
    return null;
  }

  if (head.data === value) {
    return head.next;
  }

  let current = head;

  while (current.next !== null && current.next.data !== value) {
    current = current.next;
  }

  if (current.next !== null) {
    current.next = current.next.next;
  }

  return head;
}

let head = {
  data: 10,
  next: {
    data: 20,
    next: {
      data: 30,
      next: null
    }
  }
};

head = deleteByValue(head, 20);

console.log(head.data); // 10
console.log(head.next.data); // 30
    
function deleteAtPosition(head, position) {
  if (head === null || position < 0) {
    return head;
  }

  if (position === 0) {
    return head.next;
  }

  let current = head;

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

  if (current.next !== null) {
    current.next = current.next.next;
  }

  return head;
}

let head = {
  data: 10,
  next: {
    data: 20,
    next: {
      data: 30,
      next: {
        data: 40,
        next: null
      }
    }
  }
};

head = deleteAtPosition(head, 2);

console.log(head.data); // 10
console.log(head.next.data); // 20
console.log(head.next.next.data); // 40
    

Pro Tip

For linked list deletion, think in terms of connections rather than moving data. Find the node before the target, preserve the target’s next reference, and connect the previous node directly to the next node.

🎨 IgKnight Docs

Master HTML, CSS, JS, Python, .NET and more with easy-to-follow lessons and practical code examples.

© 2025 IgKnight Learning Platform. All rights reserved.