Web Analytics

šŸ“Š Graph Representation

Intermediate ~25 min read

Think of a social network - Facebook friends, Twitter followers, LinkedIn connections. How do we store these relationships in code? Graphs are everywhere, but choosing the right representation makes all the difference!

The Graph Problem

Graphs model relationships between entities. Before we can work with graphs, we need to represent them in code:

Real-World Graphs

  • Social Networks: People (nodes) connected by friendships (edges)
  • Maps: Cities (nodes) connected by roads (edges)
  • Web: Pages (nodes) connected by links (edges)
  • Dependencies: Tasks (nodes) with prerequisites (edges)
  • Networks: Computers (nodes) connected by cables (edges)

We need a data structure that can:

  • Store vertices (nodes)
  • Store edges (connections)
  • Efficiently check if an edge exists
  • Get all neighbors of a vertex

Three Ways to Represent Graphs

The Three Representations

  1. Adjacency Matrix: VƗV matrix, matrix[i][j] = 1 if edge exists
  2. Adjacency List: Each vertex has list of neighbors
  3. Edge List: Simple list of all edges

Each has different trade-offs!

See the Representations

1. Adjacency Matrix

How It Works

Use a VƗV matrix where:

  • matrix[i][j] = 1 if edge from i to j exists
  • matrix[i][j] = 0 if no edge
  • For weighted graphs, store weight instead of 1

Adjacency Matrix Properties

  • Space: O(V²) - Always V² regardless of edges
  • Check edge: O(1) - Just matrix[i][j]
  • Get neighbors: O(V) - Scan entire row
  • Add edge: O(1) - Just set matrix[i][j]

Best for: Dense graphs (E ā‰ˆ V²), when you need fast edge lookups

Worst for: Sparse graphs (wasteful space)

2. Adjacency List

How It Works

Each vertex stores a list of its neighbors:

  • adj_list[i] = list of (neighbor, weight) tuples
  • Only stores edges that exist
  • Space-efficient for sparse graphs

Adjacency List Properties

  • Space: O(V + E) - Only stores existing edges
  • Check edge: O(degree) - Search in neighbor list
  • Get neighbors: O(degree) - Directly available
  • Add edge: O(1) - Append to list

Best for: Sparse graphs, most graph algorithms (BFS, DFS, etc.)

Worst for: Frequent edge existence checks

3. Edge List

How It Works

Simple list of all edges:

  • edges = [(from, to, weight), ...]
  • Minimal representation
  • Just stores what's needed

Edge List Properties

  • Space: O(E) - Only edges, no vertices
  • Check edge: O(E) - Must iterate all edges
  • Get neighbors: O(E) - Must search all edges
  • Add edge: O(1) - Append to list

Best for: Kruskal's algorithm, when you need to iterate all edges

Worst for: Any operation that needs quick lookups

The Complete Code

Output
Click Run to execute your code

When to Use Each Representation

Decision Guide

Representation Use When Avoid When
Adjacency Matrix Dense graph (E ā‰ˆ V²)
Need fast edge checks
Small graph
Sparse graph
Large graph (memory)
Adjacency List Sparse graph (E << V²)
Most algorithms (BFS, DFS)
Default choice
Frequent edge existence checks
Very dense graphs
Edge List Kruskal's algorithm
Need to iterate all edges
Minimal space
Need neighbor lookups
Need edge checks

Directed vs Undirected Graphs

Representation Differences

Undirected Graph:

  • Edge (u, v) means connection both ways
  • Adjacency Matrix: matrix[u][v] = matrix[v][u] = 1
  • Adjacency List: Add v to u's list AND u to v's list

Directed Graph:

  • Edge (u, v) means only u → v
  • Adjacency Matrix: Only matrix[u][v] = 1
  • Adjacency List: Only add v to u's list

Weighted Graphs

Storing Weights

  • Adjacency Matrix: Store weight at matrix[i][j] instead of 1
  • Adjacency List: Store (neighbor, weight) tuples
  • Edge List: Store (from, to, weight) tuples

Example: City distances, network latencies, social network strengths

Summary

What You've Learned

Three ways to represent graphs, each with different trade-offs:

  1. Adjacency Matrix: O(V²) space, O(1) edge check - Best for dense graphs
  2. Adjacency List: O(V + E) space, O(degree) operations - Best for most cases
  3. Edge List: O(E) space, O(E) lookups - Best for iterating edges
  4. Default choice: Adjacency list (best balance)
  5. Key insight: Choose based on graph density and operations needed

What's Next?

You've learned how to represent graphs! Next, we'll explore BFS (Breadth-First Search) - a fundamental algorithm for traversing graphs level by level, perfect for finding shortest paths in unweighted graphs!