Knowledge Guide
HomeDSAGraphs

Graph Representations

A graph representation encodes only one fact — which vertex pairs are connected — and the choice between a matrix and a list trades O(1) edge-lookup against compact, work-proportional storage, which is why the same traversal algorithm can be fast or slow purely based on how the graph is stored.

Recognize the pattern

Brute force vs optimal

Adjacency matrix (naive for sparse graphs): allocate an N×N array, set A[i][j] = 1 for each edge (both A[i][j] and A[j][i] if undirected). Edge-exists query is O(1) — direct index. But listing v's neighbors costs O(N) — you must scan the entire row even if v has only 2 neighbors — and memory is O(N2) no matter how many edges actually exist.

Adjacency list (optimal for sparse graphs): each vertex keeps a dynamic list of its neighbors. Building costs O(V + E). Listing v's neighbors costs O(deg(v)), proportional to real work. Edge-exists degrades to O(deg(v)) linear scan (or O(1) amortized if the list is backed by a hash set instead of an array).

For E « V2 the list wins on both axes — full-graph traversal becomes O(V+E) instead of O(V2). For dense graphs the two costs converge and the matrix's O(1) lookup and simplicity win.

Complexity, derived

OperationAdjacency MatrixAdjacency List
SpaceO(V²) — one cell per ordered vertex pair, always allocatedO(V + E) — one slot per vertex plus one entry per edge (two for undirected)
Edge exists? (u,v)O(1) — single array indexO(deg(u)) worst case, O(1) amortized with a hash set
Enumerate neighbors of vO(V) — must scan whole row even if deg(v) is smallO(deg(v)) — visits exactly what exists
Full traversal (BFS/DFS over all vertices)O(V²) — each vertex scans a row of VO(V + E) — each edge is touched a constant number of times
Add edgeO(1)O(1) (append to list)

The O(V+E) traversal bound for lists comes directly from summing degrees. For undirected graphs, ∑deg(v) = 2E (handshake lemma) — each edge is counted once from each endpoint — so visiting every vertex's list exactly once costs O(V) for the vertex loop plus O(2E) = O(E) for the edge visits, giving O(V+E), not O(V·E). For directed graphs — like the worked example below — the same argument uses out-degree instead: ∑outdeg(v) = E exactly, with no factor of 2, because each directed edge is counted once, from its source vertex only. The vertex loop is still O(V) and the total edge visits are still O(E), so the bound is O(V+E) either way — the handshake lemma just supplies the factor of 2 for undirected graphs and drops it for directed ones.

Worked example

Directed graph, 4 vertices (A=0, B=1, C=2, D=3), edges A→B, A→C, C→D, D→B, D→C.

Adjacency matrix (row = from, col = to):

ABCD
A0110
B0000
C0001
D0110

Adjacency list (same graph): A → [B, C]; B → []; C → [D]; D → [B, C].

Storage check: matrix uses 16 cells regardless of edge count; list uses 4 head slots + 5 entries = 9 units — cheaper here, and the gap widens as N grows while E stays small.

Java: both representations for the worked example

import java.util.*;

public class GraphRepresentations {
    public static void main(String[] args) {
        int n = 4; // A=0, B=1, C=2, D=3
        int[][] edges = {{0,1}, {0,2}, {2,3}, {3,1}, {3,2}};

        // Adjacency matrix
        int[][] matrix = new int[n][n];
        for (int[] e : edges) matrix[e[0]][e[1]] = 1; // directed

        // Adjacency list
        List> adj = new ArrayList<>();
        for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
        for (int[] e : edges) adj.get(e[0]).add(e[1]);

        System.out.println("Matrix row A: " + Arrays.toString(matrix[0]));
        System.out.println("List for A: " + adj.get(0));
    }
}

Pitfalls

When to use / when not

Adjacency matrix — use when the graph is dense, N is small (roughly N ≤ 1000), or you need frequent O(1) edge-existence checks (e.g. Floyd-Warshall all-pairs shortest path, which is inherently O(V3) and matrix-native). Avoid when N is large or the graph is sparse — you pay O(V2) memory for edges that mostly don't exist.

Adjacency list — use for sparse graphs, BFS/DFS, Dijkstra, topological sort, or any large-N graph. Avoid when you need frequent arbitrary edge-existence checks at scale without a backing hash set, since that degrades to O(deg(v)).

Named alternative — edge list (a flat array of (u, v[, w]) triples): more compact to build than either (O(E) to construct, no per-vertex bookkeeping) and is what Kruskal's MST algorithm wants directly since it needs edges sorted by weight, not grouped by vertex. But it's the worst for neighbor queries — O(E) scan to find v's neighbors — so it's rarely used for traversal.

Takeaways

Recall: Why does full-graph BFS/DFS cost O(V²) on an adjacency matrix but O(V+E) on an adjacency list, even though both visit every vertex once?


Synthesized from standard adjacency matrix/list treatments (CLRS graph representations chapter) and common interview-prep graph traversal material.

🤖 Don't fully get this? Learn it with Claude

Stuck on Graph Representations? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Graph Representations** (DSA) and want to truly understand it. Explain Graph Representations from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Graph Representations** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Graph Representations** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Graph Representations** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes