Memra

Graph representations: lists vs matrices

◈ 6 cards

Adjacency list vs adjacency matrix — space, edge-test cost, and how we model graphs in Python.

Two ways to store a graph

A graph has a vertex set and an edge set . Throughout graph analysis we abuse notation and write for and for inside asymptotic bounds. There are two standard representations, and choosing the right one is a recurring exam justification.

Adjacency list. An array (or dict) Adj of lists. Adj[u] holds every vertex with .

  • Space: — one slot per vertex plus one list entry per edge.
  • Edge test ? — you must scan 's list.
  • Best for sparse graphs (), which is almost every real graph.

Adjacency matrix. A matrix with iff .

  • Space: regardless of edge count.
  • Edge test: — one array lookup.
  • Best for dense graphs ( near ) or when you need constant-time edge queries.

Why CLRS defaults to lists

Most graphs are sparse, and BFS, DFS, topological sort, and SCC all run in only with adjacency lists — the list lets each algorithm touch every vertex and every edge exactly once (aggregate analysis). On an adjacency matrix, "scan all neighbours of " costs per vertex, dragging those same algorithms up to even on a sparse graph.

Worked example — the scale argument. A social network with users and friendships needs list space but matrix space — the matrix is physically impossible. For a complete graph the two converge: , so a list costs too, and the matrix's edge test wins.

How we model graphs in Python

We use a dict of lists: {u: [v1, v2, ...]}. A directed edge appends v to adj[u] only; an undirected edge appends both directions. The transpose reverses every edge — needed later for strongly connected components.

01243|V| = 5, |E| = 6 — sparse.
One graph, three figures. This is the shape; the next two are the two ways to store it.
Adj[0]14Adj[1]023Adj[2]13Adj[3]124Adj[4]0312 entries = 2|E|
Adjacency list — Θ(V+E) space: five rows plus twelve entries, because an undirected edge is stored at both of its ends. Testing (1,4) ∈ E means scanning Adj[1] and not finding 4.
01234001001110110201010301101410010A[i][j] = 1 iff (i,j) ∈ E
Adjacency matrix — Θ(V²) whatever the density: 25 slots for 6 edges, and still 25 slots if you delete every edge. What it buys is A[1][4], one lookup instead of a scan.
adjacency listadjacency matrixspaceΘ(V+E)Θ(V²)(u,v) ∈ E?O(deg(u))O(1)scan Adj[u]Θ(deg(u))Θ(V)BFS / DFSΘ(V+E)Θ(V²)use whensparsedenseSparse is the common case — hence the CLRS default.
The matrix wins exactly one row — the O(1) edge test. Every other row favours the list, which is why CLRS defaults to it.
NORMAL ~/memra/learn/comp-372/graph-representations utf-8 LF