An adjacency list, like an Adjacency Matrix, is a way of representing a graph. However, instead of using a 2D array, it uses a collection of lists or arrays to represent the connections between nodes. This representation is more space-efficient for sparse graphs, where the number of edges is much less than the maximum possible number of edges. One can picture this as looking somewhat like a Hash Map.
Once again consider that one undirected graph example, we can represent this as a Adjacency List with the following:
Where it is defined as follows:
- Let be a graph.
- The adjacency list is a mapping of neighbors such that:
- Directed graphs: if and only if .
- Undirected graphs: if and only if ; equivalently, as well.
- Weighted graphs: each entry in Adj[u] is a pair (v, w(u, v)); for unweighted graphs, each entry is just v.
- Multigraphs/self-loops: duplicates and u = v entries may appear in Adj[u] as permitted by E.
- Space usage: Theta(|V| + |E|).
- Basic operations:
- neighbors(u): iterate Adj[u] in O(deg(u)).
- hasEdge(u, v): O(deg(u)) with plain lists; average O(1) if Adj[u] is backed by a hash/set.
- addEdge(u, v[, w]): amortized O(1); for undirected graphs also insert v into Adj[u] and u into Adj[v].
- removeEdge(u, v): O(deg(u)) with lists; average O(1) with indexed structures.