Graphs

adjacency list

An adjacency list is the most common way to store a graph: for every vertex you keep a list of the vertices it is directly connected to. Think of a phone contact book where each person has their own short list of who they can call. To find a vertex's neighbors you go straight to its list — no searching the whole graph.

Compare it to the other classic choice, the adjacency matrix: a V-by-V grid where cell [i][j] is 1 if there is an edge from i to j and 0 otherwise. The matrix makes the question 'is there an edge between i and j?' instant, but it always uses O(V^2) space even when the graph is sparse (few edges). An adjacency list uses O(V + E) space — one slot per vertex plus one entry per edge — which is dramatically smaller for the sparse graphs that show up most in practice (road maps, social networks). Its trade-off is that checking a single specific edge means scanning one vertex's list.

Because traversals like breadth-first and depth-first search visit each vertex and walk along each edge, the adjacency list's O(V + E) layout is exactly what lets those algorithms run in O(V + E) time. That is why it is the default representation in most algorithm code.

vector<vector<int>> adj(3);     // 3 vertices
adj[0] = {1, 2};
adj[1] = {0, 2};
adj[2] = {0, 1};
// neighbors of vertex 0:
for (int nb : adj[0]) { /* visit nb */ }

adj[v] holds every vertex directly reachable from v. Add edges both ways if undirected.

Rule of thumb: adjacency list for sparse graphs (E much smaller than V^2), adjacency matrix when the graph is dense or you need instant edge lookups.

Also called
邻接链表鄰接串列