Time complexity measures how operations scale with list size. Linked lists excel at head operations (O(1)) but require traversal for access/search (O(n)). Space complexity is O(n) for n nodes, but each node requires extra memory for pointers — a 'hidden tax' that arrays don't pay.
Time: Accessing the 5th element — Arrays jump directly (O(1)). Linked lists must traverse 5 nodes (O(n)). But inserting at the front — Arrays shift everyone (O(n)), linked lists just update two pointers (O(1)). Space: Array of 100 integers = 400 bytes. Linked list = 1200 bytes (400 data + 800 pointers).
| Action | Speed | Analogy |
|---|---|---|
| Access / Search | O(n) | Asking everyone "Are you Bob?" until you find him. |
| Insert (Head) | O(1) | Cutting in line at the very front. |
| Insert (Tail) | O(n) | Walking to the back of the line to join. |
| Insert (Position i) | O(i) or O(n) | Walking to position i, then inserting. |
| Delete (Head) | O(1) | Removing the first person in line — instant! |
| Delete (Tail) | O(n) | Finding the second-to-last person to update their pointer. |
| Delete (Position i) | O(i) or O(n) | Walking to position i, then updating previous node's pointer. |
Space Complexity: The Hidden Tax
Space Complexity is O(n). But there is a catch!
Every node needs extra memory for the next pointer.
You pay for the map to the next treasure!
For 100 integers: Array = 400 bytes. Linked List = 1200 bytes (3x more!)
Time Complexity
Access / Search: O(n)
You cannot jump to index i. You must start at head and traverse i nodes. Worst case: element is at the end or not found = n steps.
Insert at Head: O(1)
The golden operation! No traversal needed. Create node, link it, update head. Three pointer assignments, always constant time.
Insert at Tail: O(n)
You must traverse to find the last node (the one pointing to NULL). Then link it. This is why maintaining a tail pointer helps — it makes tail insertion O(1) too.
Insert at Position i: O(i) or O(n)
You must traverse i nodes to reach position i, then insert. Worst case (i = n) is O(n).
Delete at Head: O(1)
Just move head to head->next. Free the old head. No traversal.
Delete at Tail: O(n)
You need to find the second-to-last node to update its pointer to NULL. This requires traversal. Again, a tail pointer helps but deletion still needs the previous node.
Delete at Position i: O(i) or O(n)
Traverse to position i, update previous node's pointer. Worst case O(n).
Space Complexity
The Memory Breakdown
For a singly linked list storing integers:
For 100 nodes: 1200 bytes total (400 data + 800 pointers)
The Array Comparison
An array of 100 integers: 400 bytes total. No pointers needed because elements are neighbors — the computer calculates addresses mathematically.
When Overhead Hurts
Doubly Linked Lists
Even worse! Two pointers per node = 16 bytes overhead. 100 nodes = 400 data + 1600 pointers = 2000 bytes total.
The Trade-off
You pay extra memory for the flexibility of dynamic size and easy insertion/deletion. Sometimes it's worth it, sometimes arrays are better.
Understanding complexity helps you choose the right data structure. If you need frequent head insertions, linked lists win. If you need random access, arrays win. Space overhead matters for small data types — storing 100 integers takes 3x more memory than arrays due to pointer overhead.
"What is the time complexity of deleting the last node, and why does space complexity include overhead?"
Delete at tail is O(n) — you must traverse to find the second-to-last node. Space is O(n) but with pointer overhead — each node needs extra memory for pointers (8 bytes per pointer on 64-bit systems), making it less memory-efficient than arrays for small data types.