What is a Linked List?
A Linked List is a linear data structure where elements (nodes) are stored at scattered memory locations and connected by pointers. Each node holds data plus a reference to the next node.
Unlike arrays, nodes are not contiguous. There is no index arithmetic: to reach the k-th node you must walk the chain from the head, making access O(n). The payoff is O(1) insert/delete once you hold the node, with no shifting.
Node layout
struct Node {
int data;
Node* next;
};
// head → [10|•]→[20|•]→[30|/]
// each • is a pointer, / is nullptr
Linked list structure — nodes, pointers, and traversal
next pointer stitches them together. No cache locality, so traversal is slower than arrays.prev and next. Traverse both directions, delete a node in O(1) given only that node.next points back to head (singly or doubly). No null terminator.next is nullptr (or head, if circular).next points to an earlier node, forming a loop. Detected with Floyd's algorithm.Walk from the head; no random access.
Point new node at head, move head.
O(1) with a tail pointer, else O(n).
O(n) to reach the spot, O(1) to splice.
Doubly linked, or with the predecessor.
Single pass, O(1) extra space.
Visit each node once, cache-unfriendly.
n nodes plus one pointer each.
Floyd's tortoise & hare, O(1) space.
| Aspect | Array | Linked List |
|---|---|---|
| Memory | Contiguous | Scattered (heap) |
| Random access | O(1) | O(n) |
| Insert/delete at front | O(n) | O(1) |
| Cache locality | Excellent | Poor |
| Memory overhead | None | Pointer per node |
| Resizing | Reallocate + copy | Grow node by node |
| Use case | Indexing, scanning | Frequent splice, unknown size |
Advantages
- O(1) insertion/deletion at the front (and anywhere given the node).
- Grows and shrinks one node at a time — no reallocation.
- No wasted capacity; size is exactly the node count.
- Splicing/merging lists is pointer rewiring, not copying.
- Foundation for stacks, queues, deques, adjacency lists, LRU caches.
Disadvantages
- No random access — reaching index k is O(n).
- Poor cache locality; traversal is slower than arrays.
- Extra memory for pointers (8+ bytes per node).
- Reverse traversal impossible in singly linked lists.
- Pointer bugs: dangling pointers, leaks, lost heads.
struct Node { int data; Node* next; Node(int v) : data(v), next(nullptr) {} }; // Insert at head — O(1) Node* insertHead(Node* head, int v) { Node* node = new Node(v); node->next = head; return node; // new head } // Insert at index — O(n) Node* insertAt(Node* head, int idx, int v) { if (idx == 0) return insertHead(head, v); Node* cur = head; for (int i = 0; i < idx - 1 && cur; i++) cur = cur->next; Node* node = new Node(v); node->next = cur->next; cur->next = node; return head; } // Delete first node with value — O(n) Node* deleteVal(Node* head, int v) { if (!head) return head; if (head->data == v) { Node* t = head->next; delete head; return t; } Node* cur = head; while (cur->next && cur->next->data != v) cur = cur->next; if (cur->next) { Node* t = cur->next; cur->next = t->next; delete t; } return head; } // Traverse — O(n) void print(Node* head) { for (Node* c = head; c; c = c->next) cout << c->data << " -> "; cout << "null\n"; }
#include <bits/stdc++.h> using namespace std; int main() { list<int> dll = {10, 20, 30}; // doubly linked dll.push_front(5); // O(1) dll.push_back(40); // O(1) auto it = dll.begin(); ++it; dll.insert(it, 15); // O(1) given iterator dll.erase(dll.begin()); // O(1) forward_list<int> sll = {1, 2, 3}; // singly linked sll.push_front(0); // O(1) sll.reverse(); // O(n) for (int x : dll) cout << x << " "; return 0; }
Step-by-step operation log
| Step | Current | Value | Action | List State | Ptr ops |
|---|---|---|---|---|---|
| Run a scenario to populate the log. | |||||
slow one node and fast two per step. If they meet, there's a cycle. When fast hits the end, slow sits on the middle. Also finds the k-th node from the end by offsetting the pointers.// Reverse in-place — O(n) time, O(1) space Node* reverse(Node* head) { Node* prev = nullptr; while (head) { Node* nxt = head->next; head->next = prev; // flip link prev = head; head = nxt; } return prev; // new head } // Middle node (slow/fast) — O(n) Node* middle(Node* head) { Node* slow = head; Node* fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; } return slow; } // Detect cycle (Floyd) — O(n) time, O(1) space bool hasCycle(Node* head) { Node* slow = head; Node* fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; if (slow == fast) return true; } return false; }
next before flipping a link (you'll orphan the rest of the list), off-by-one when finding the middle of an even-length list, and not handling the empty/single-node list in every operation.| Operation | Time | Space | Notes |
|---|---|---|---|
| Access k-th | O(n) | O(1) | Walk from head, no index math |
| Search | O(n) | O(1) | Linear scan of the chain |
| Insert head | O(1) | O(1) | Rewire two pointers |
| Insert tail | O(1)† | O(1) | O(1) with tail pointer |
| Insert at index | O(n) | O(1) | Reach spot, then splice |
| Delete node | O(1) | O(1) | Given node (doubly) / predecessor |
| Reverse | O(n) | O(1) | Three-pointer flip |
| Detect cycle | O(n) | O(1) | Floyd's tortoise & hare |
| Merge two sorted | O(n+m) | O(1) | Splice with dummy head |
Node & Pointer Basics
Build a node struct, link three nodes by hand, traverse and print. Understand head vs tail.
Core Operations
Insert head/tail/index, delete by value/index, search. Handle empty and single-node cases.
Reversal & Dummy Nodes
In-place iterative reversal, recursive reversal, and using a sentinel to kill edge cases.
Fast/Slow Pointers
Middle node, cycle detection, cycle start, k-th from end, palindrome check.
Doubly & Circular
Bidirectional traversal, O(1) delete, circular buffers, and the LRU cache pattern.
Hard Problems
Merge k sorted lists, reverse in groups of k, copy list with random pointer, flatten multilevel.
next = curr->next, or you lose the rest of the list.dummy.next at the end.next before flipping. Recursion returns the new head from the tail.