Linked List Operations (Insertion, Deletion, Traversal)
Linked List Operations: Insertion, Deletion, Traversal
Building on our understanding of nodes and list types, let’s dive into the core operations you’ll perform on linked lists. We’ll use a singly linked list as our primary example, but note the same concepts apply with minor pointer‐adjustments in doubly or circular variants. As always, N denotes the current number of nodes in the list.
1. Insertion
1.1. At Head: .prepend(value)
Adds a new node before the current head.
-
Concept:
- Create a new node.
- Point its
.nextto the old head. - Update
headto the new node. - If the list was empty, also set
tailto the new node. - Increment
length.
-
Time Complexity:
O(1)(constant pointer updates) -
Space Complexity:
O(1)(one new node)
prepend(value) {
const newNode = new Node(value);
newNode.next = this.head;
this.head = newNode;
if (!this.tail) this.tail = newNode;
this.length++;
}
1.2. At Tail: .append(value)
Adds a new node after the current tail.
-
Concept:
- Create a new node.
- If the list is empty, set both
headandtailto it. - Otherwise, link the old
tail.nextto the new node and updatetail. - Increment
length.
-
Time Complexity:
O(1)(direct tail pointer) -
Space Complexity:
O(1)
append(value) {
const newNode = new Node(value);
if (!this.head) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
this.tail = newNode;
}
this.length++;
}
1.3. At Arbitrary Position: .insertAt(index, value)
Inserts a node at a given zero-based index.
-
Concept:
- Validate
index(0 ≤ index ≤ length). - If
index === 0, delegate to.prepend(). - If
index === length, delegate to.append(). - Otherwise, traverse to the node just before the target position.
- Splice in the new node.
- Increment
length.
- Validate
-
Time Complexity:
O(N)(may traverse up toindex) -
Space Complexity:
O(1)
insertAt(index, value) {
if (index < 0 || index > this.length) return false;
if (index === 0) return this.prepend(value);
if (index === this.length) return this.append(value);
const newNode = new Node(value);
let prev = this.head;
for (let i = 1; i < index; i++) {
prev = prev.next;
}
newNode.next = prev.next;
prev.next = newNode;
this.length++;
return true;
}
2. Deletion
2.1. Remove Head: .removeHead()
Deletes the first node and returns its value.
-
Concept:
- If empty, return
null. - Store the old head.
- Update
headtohead.next. - If now empty, also clear
tail. - Decrement
length. - Return removed value.
- If empty, return
-
Time Complexity:
O(1) -
Space Complexity:
O(1)
removeHead() {
if (!this.head) return null;
const removed = this.head;
this.head = this.head.next;
if (!this.head) this.tail = null;
this.length--;
return removed.value;
}
2.2. Remove Tail: .removeTail()
Deletes the last node and returns its value.
-
Concept:
- If empty, return
null. - If only one node, clear both
headandtail. - Otherwise, traverse to the node just before the tail.
- Update its
.nexttonulland set it as newtail. - Decrement
length. - Return removed value.
- If empty, return
-
Time Complexity:
O(N)(must find the penultimate node) -
Space Complexity:
O(1)
removeTail() {
if (!this.head) return null;
if (this.head === this.tail) {
const val = this.head.value;
this.head = null;
this.tail = null;
this.length--;
return val;
}
let curr = this.head;
while (curr.next !== this.tail) {
curr = curr.next;
}
const val = this.tail.value;
curr.next = null;
this.tail = curr;
this.length--;
return val;
}
2.3. Remove at Index: .removeAt(index)
Deletes a node at a specified index.
-
Concept:
- Validate
index(0 ≤ index < length). - If
index === 0, delegate to.removeHead(). - If
index === length − 1, delegate to.removeTail(). - Otherwise, traverse to the node just before the target.
- Splice out the target node.
- Decrement
length. - Return removed value.
- Validate
-
Time Complexity:
O(N) -
Space Complexity:
O(1)
removeAt(index) {
if (index < 0 || index >= this.length) return null;
if (index === 0) return this.removeHead();
if (index === this.length - 1) return this.removeTail();
let prev = this.head;
for (let i = 1; i < index; i++) {
prev = prev.next;
}
const removed = prev.next;
prev.next = removed.next;
this.length--;
return removed.value;
}
3. Traversal & Search
3.1. Traverse: .traverse(callback)
Visits each node in order, invoking a provided callback on its value.
-
Concept:
- Start at
head. - While current node exists, call
callback(current.value). - Advance to
current.next.
- Start at
-
Time Complexity:
O(N) -
Space Complexity:
O(1)
traverse(callback) {
let curr = this.head;
while (curr) {
callback(curr.value);
curr = curr.next;
}
}
3.2. Search: .find(value)
Locates the first node containing the given value.
-
Concept:
- Iterate from
headtonull. - If
current.value === value, return the node. - If end is reached, return
null.
- Iterate from
-
Time Complexity:
O(N) -
Space Complexity:
O(1)
find(value) {
let curr = this.head;
while (curr) {
if (curr.value === value) return curr;
curr = curr.next;
}
return null;
}
Tip: Always keep track of length and tail pointers when relevant—they let you optimize many operations to O(1). For operations at arbitrary positions, expect linear time due to traversal.

