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.
Discussion
Sign in to join the discussion.

