Adjacency Matrix versus Adjacency Lists
Two Standard Representations
There are two fundamental ways to store a graph in memory. The choice of representation directly affects the asymptotic running time of graph algorithms, so understanding the trade-offs is critical for both implementation decisions and exam questions.
Adjacency Matrix
An adjacency matrix is a matrix . For unweighted graphs:
For weighted graphs, stores the edge weight (and typically , 0, or some sentinel for absent edges). For undirected graphs, the matrix is symmetric: . This means only the upper or lower triangle needs to be stored explicitly, roughly halving the memory. For unweighted graphs, each entry can be a single bit.
Space: regardless of the number of edges. Even a graph with zero edges allocates a full matrix.
Key operations:
- Test if : — single array lookup.
- List all neighbours of vertex : — must scan the entire row .
- Iterate over all edges: — must visit every matrix cell.
- Add or remove an edge: — set or clear a cell.
Adjacency Lists
An array of length , where points to a linked list or dynamic array containing all such that . For weighted graphs, each list entry stores .
Space: . Each directed edge contributes one list entry. For undirected graphs, each edge appears in two lists, so space is .
Key operations:
- Test if : — sequential scan of ‘s list. Worst case when .
- List neighbours of : — exactly the list length.
- Iterate over all edges: — visit each list head and each entry once.
- Add edge: (prepend to list). Remove edge: (find and delete).
- For undirected graphs, removal must be done from both endpoints’ lists: .
Worked Example
Directed weighted graph: , edges weight 5, weight 2, weight 1.
Matrix representation:
Adjacency list representation:
Space analysis: matrix uses entries. Lists use 3 list entries + 4 array slot pointers = 7 entries. For this sparse graph ( of a possible 12), lists are significantly more compact.
Trade-off Summary
| Criterion | Adjacency Matrix | Adjacency Lists |
|---|---|---|
| Space | ||
| Edge query | ||
| Neighbours of | ||
| All edges iteration | ||
| Add edge | ||
| Remove edge | ||
| Best for | Dense graphs | Sparse graphs |
Impact on Graph Algorithms
BFS/DFS: With adjacency lists, both run in because the inner loop visits each neighbour exactly once. With an adjacency matrix, the inner loop must scan all columns for each dequeued/extracted vertex, costing per vertex. Total: regardless of edge count.
Exam point (y2025p1q9): Tight bounds for BFS with adjacency matrix are and ; with lists, and .
Dijkstra: With binary heap and adjacency lists: . With matrix: neighbour iteration becomes per vertex, and using a simple array instead of heap gives , which can be faster than for dense graphs due to lower constants.
Floyd-Warshall: Inherently uses a matrix (the distance matrix itself), running in . Johnson’s algorithm relies on adjacency lists for sparsely efficient Dijkstra calls.
Summary
| Property | Matrix | Lists |
|---|---|---|
| Space | ||
| Edge test | worst | |
| Neighbour listing | ||
| BFS/DFS time | ||
| Use when |
Past paper questions: y2025p1q9(a)(i) (BFS complexity bounds with adjacency matrix).