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.nextwhen 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.