Adjacency List vs Matrix When to Choose Which in DSA Python - Complexity Comparison
When working with graphs, choosing how to store connections affects how fast we can check or add links.
We want to know how the time to do these tasks grows as the graph gets bigger.
Analyze the time complexity of checking if an edge exists between two nodes using adjacency list and adjacency matrix.
# Using adjacency list
def has_edge_list(graph, u, v):
return v in graph[u]
# Using adjacency matrix
def has_edge_matrix(matrix, u, v):
return matrix[u][v] == 1
This code checks if there is a direct connection from node u to node v in two different graph representations.
Look at what repeats when checking for an edge.
- Primary operation: Searching for node v in u's neighbors (list) or direct access in matrix.
- How many times: In list, it depends on how many neighbors u has; in matrix, it's a single direct check.
For adjacency list, checking an edge takes longer if node u has many neighbors.
| Input Size (n) | Approx. Operations (List) | Approx. Operations (Matrix) |
|---|---|---|
| 10 | Up to 9 checks | 1 check |
| 100 | Up to 99 checks | 1 check |
| 1000 | Up to 999 checks | 1 check |
Pattern observation: List search grows with neighbors count; matrix access stays constant.
Time Complexity: O(k) for adjacency list, where k is neighbors count; O(1) for adjacency matrix.
This means checking an edge is faster with a matrix but can be slower with a list if many neighbors exist.
[X] Wrong: "Adjacency matrix is always better because it is faster to check edges."
[OK] Correct: Matrix uses much more memory and can be slow to build for large sparse graphs, making lists better in many cases.
Understanding these differences helps you pick the right graph storage for the problem, showing you know both speed and memory trade-offs.
What if the graph is very dense? How would the time complexity of adjacency list and matrix compare then?
Practice
Solution
Step 1: Understand graph density
A graph with very few edges compared to vertices is called a sparse graph.Step 2: Choose efficient representation for sparse graphs
Adjacency lists store only existing edges, saving space for sparse graphs, unlike adjacency matrices which use space for all possible edges.Final Answer:
Adjacency List -> Option AQuick Check:
Sparse graph = Adjacency List [OK]
- Choosing adjacency matrix for sparse graphs wastes space
- Confusing edge list with adjacency matrix
- Assuming adjacency matrix is always better
Solution
Step 1: Understand matrix initialization
Using list comprehension with nested loops creates independent inner lists.Step 2: Avoid shallow copies
matrix = [[0]*4]*4 creates shallow copies causing all rows to reference the same list, leading to bugs.Final Answer:
matrix = [[0 for _ in range(4)] for _ in range(4)] -> Option AQuick Check:
Independent rows = matrix = [[0 for _ in range(4)] for _ in range(4)] [OK]
- Using [[0]*4]*4 causes all rows to be the same object
- Initializing with single list for matrix
- Using None instead of 0 for adjacency matrix
graph = {0: [1, 2], 1: [2], 2: []}
print(graph[1])What is the output?
Solution
Step 1: Understand adjacency list structure
Key 1 maps to list [2], meaning vertex 1 connects to vertex 2.Step 2: Print value for key 1
graph[1] returns [2], so print outputs [2].Final Answer:
[2] -> Option CQuick Check:
graph[1] = [2] [OK]
- Confusing keys and values in dictionary
- Expecting all vertices in output
- Assuming KeyError for existing key
matrix = [[0]*3]*3 matrix[0][1] = 1 print(matrix)
What is the output and what is the bug?
Solution
Step 1: Understand matrix initialization
Using [[0]*3]*3 creates 3 references to the same inner list.Step 2: Modify one element affects all rows
Setting matrix[0][1] = 1 changes the second element in all rows because they share the same list.Final Answer:
[[0, 1, 0], [0, 1, 0], [0, 1, 0]]; Rows are shallow copies -> Option DQuick Check:
Shallow copy rows cause all rows to change [OK]
- Assuming only first row changes
- Ignoring shallow copy behavior
- Confusing IndexError with shallow copy bug
Solution
Step 1: Analyze graph density and operations
Graph has 1000 vertices and 10,000 edges, which is moderately sparse but not very sparse.Step 2: Consider operation speed for edge checks
Adjacency matrix allows checking edge existence in constant time O(1), while adjacency list requires searching neighbors.Step 3: Balance memory and speed
Though adjacency matrix uses more memory, the speed benefit for frequent edge checks outweighs memory cost here.Final Answer:
Adjacency Matrix, because it allows O(1) edge existence checks -> Option BQuick Check:
Frequent edge check = Adjacency Matrix [OK]
- Choosing adjacency list only for memory without considering speed
- Ignoring operation frequency in choice
- Confusing edge list with adjacency matrix for fast checks
Ready to prove it?
Pass the test and this pattern moves unknown
