Values live in separate nodes chained by pointers — instant insert at the head, but reaching the k-th element means walking the chain.
A linked list stores each value in its own little box — a node — that also holds a pointer to the next node, chaining them together. Unlike an array, the boxes aren't packed side by side in memory; they can sit anywhere, linked only by those pointers. That single design choice flips an array's trade-offs on their head.
next pointer to the following node.next points to null, marking the end (the tail).next from the head, node by node.class Node {
constructor(value) { this.value = value; this.next = null; }
}
// insert at head — O(1), just repoint two links
function prepend(head, value) {
const node = new Node(value);
node.next = head; // new node points at the old head
return node; // new node is the new head
}Once you *hold* a node, splicing around it is O(1) — you just rewire next pointers, no elements move. To insert after a node, point the new node at the node's successor, then point the node at the new node. To delete the next node, point node.next past it to node.next.next. The cost is never the rewiring; it's *getting to* the spot, which takes a traversal.
// delete the node after `node` — O(1) once you're there
function deleteAfter(node) {
if (node.next) node.next = node.next.next; // skip over it
}