Quiz 2

20. Graph Representations — Adjacency Matrix & List

606 words
3 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# 20. Graph Representations — Adjacency Matrix & List > **What problem does this solve?** Graphs model relationships: road networks, social media connections, web pages.

20. Graph Representations — Adjacency Matrix & List

What problem does this solve? Graphs model relationships: road networks, social media connections, web pages. Before we can traverse or analyze graphs, we need to store them. Two standard representations offer different trade-offs.

1. Graph Terminology

TermDefinition
Vertex (node)Entity in the graph
EdgeConnection between two vertices
Directed graphEdges have direction (u→v ≠ v→u)
Undirected graphEdges are bidirectional
Weighted graphEdges have costs/weights
PathSequence of vertices connected by edges
CyclePath that starts and ends at same vertex
AdjacentTwo vertices connected by an edge
DegreeNumber of edges incident to a vertex
(Diagram)

2. Adjacency Matrix

How It Works

A |V| × |V| matrix where matrix[u][v] = 1 (or weight) if there's an edge u→v. (Diagram)

Implementation

python
# runnable
import numpy as np
class GraphMatrix:
    """Graph using adjacency matrix (NumPy)."""
    def __init__(self, vertices, directed=False):
        self.n = vertices
        self.directed = directed
        # 3D matrix: [is_edge, weight] per cell
        self.M = np.zeros(shape=(vertices, vertices, 2))
    def add_edge(self, u, v, weight=1):
        self.M[u, v, 0] = 1
        self.M[u, v, 1] = weight
        if not self.directed:
            self.M[v, u, 0] = 1
            self.M[v, u, 1] = weight
    def has_edge(self, u, v):
        return self.M[u, v, 0] == 1
    def get_weight(self, u, v):
        return self.M[u, v, 1] if self.has_edge(u, v) else float('inf')
    def neighbors(self, u):
        """Return list of neighbors of vertex u."""
        return [v for v in range(self.n) if self.M[u, v, 0] == 1]
# Test
gm = GraphMatrix(4, directed=False)
gm.add_edge(0, 1, 5)
gm.add_edge(0, 2, 2)
gm.add_edge(1, 2, 3)
gm.add_edge(2, 3, 1)
print(f"Edge 0→1: {gm.has_edge(0, 1)}")  # True
print(f"Neighbors of 0: {gm.neighbors(0)}")  # [1, 2]
print(f"Weight 0→2: {gm.get_weight(0, 2)}")  # 2.0

3. Adjacency List

How It Works

For each vertex, store a list of its neighbors (and optionally edge weights).
python
# runnable
class GraphList:
    """Graph using adjacency list (dictionary)."""
    def __init__(self, vertices=None, directed=False):
        self.directed = directed
        self.adj = {}  # vertex → list of (neighbor, weight)
        if vertices:
            for v in range(vertices):
                self.adj[v] = []
    def add_vertex(self, v):
        if v not in self.adj:
            self.adj[v] = []
    def add_edge(self, u, v, weight=1):
        self.add_vertex(u)
        self.add_vertex(v)
        self.adj[u].append((v, weight))
        if not self.directed:
            self.adj[v].append((u, weight))
    def neighbors(self, u):
        return self.adj.get(u, [])
    def vertices(self):
        return list(self.adj.keys())
# Test
gl = GraphList(directed=False)
gl.add_edge(0, 1, 5)
gl.add_edge(0, 2, 2)
gl.add_edge(1, 2, 3)
gl.add_edge(2, 3, 1)
print(f"Adjacency list: {gl.adj}")
# {0: [(1, 5), (2, 2)], 1: [(0, 5), (2, 3)],
#  2: [(0, 2), (1, 3), (3, 1)], 3: [(2, 1)]}

4. Comparison

FeatureAdjacency MatrixAdjacency List
Space(O(V
Edge lookup(O(1))(O(degree))
List all neighbors(O(V
Add edge(O(1))(O(1))
Remove edge(O(1))(O(degree))
Best forDense graphs (E
Rule of thumb: Use adjacency list for most real-world graphs (they're sparse). Use matrix when |V| ≤ 1000 and you need fast edge lookups.

Practice Questions

Q1. How much memory does an adjacency matrix use for |V| = 1000? What about an adjacency list with |E| = 5000? Q2. Why is adjacency list preferred for BFS/DFS on sparse graphs? Q3. Convert this edge list to adjacency list: [(0,1), (0,2), (1,2), (2,3)] Q4. What's the maximum number of edges in a directed graph with n vertices?
Answers
A1. Matrix: 1000 × 1000 = 1,000,000 entries. List: 1000 lists with 10,000 total entries (each edge stored twice for undirected).
A2. BFS/DFS explores neighbors. With adjacency list, iterating over neighbors of a vertex takes O(degree), not O(|V|). For sparse graphs, this is much faster.
A3. {0: [1, 2], 1: [0, 2], 2: [0, 1, 3], 3: [2]}
A4. (n(n-1)) (no self-loops). Each vertex can connect to every other vertex. Join Discord Previous19. Heap SortNext21. BFS & DFS — Graph Traversals
Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.