Interactive notes for graph vocabulary, edge types, graph types, tree intuition, representations, and a live graph builder.
A thing — a data point, a place, a person, an entity.
Drawn as a circle. Holds a value or label.
A connection between two nodes — drawn as a line between circles.
Can carry direction, weight, or just be a plain link.
Click on any circle or line below to learn more:
Edges carry different properties depending on the problem you're modelling.
undirected: graph['A'].append('B')
graph['B'].append('A')
directed: graph['A'].append('B')
# B does NOT point back to A
weighted: graph['A'].append(('B', 42))
# tuple: (neighbor, weight)
| Edge type | Real example |
|---|---|
| Undirected | WhatsApp contact |
| Directed | Instagram follow |
| Weighted | Flight price |
| Self-loop | A page linking to itself |
Binary — each node has at most 2 children (left & right)
Search — organized for fast searching: left < node < right
Tree — hierarchical, acyclic structure with one root
left < node < right
For every node: everything in its left subtree is smaller, everything in its right subtree is larger.
Search for value: —
Each comparison eliminates half the tree. With 1,000,000 nodes: only ~20 comparisons needed. That's the power of O(log n) vs O(n) linear search.
def search(node, target):
if not node or node.val == target:
return node # found or not here
if target < node.val:
return search(node.left, target) # go left
return search(node.right, target) # go right
from collections import defaultdict
graph = defaultdict(list)
graph['A'].append('B')
graph['A'].append('C')
graph['B'].append('D')
graph['C'].append('D')
# Result:
# {'A': ['B', 'C'], 'B': ['D'], 'C': ['D'], 'D': []}
Space: O(V + E). Best for sparse graphs.
graph = defaultdict(list)
graph['A'].append(('B', 5)) # (neighbor, weight)
graph['A'].append(('C', 3))
graph['B'].append(('D', 8))
# Iterate over weighted neighbors:
for neighbor, weight in graph['A']:
print(neighbor, weight) # B 5, then C 3
# 4 nodes: A=0, B=1, C=2, D=3
matrix = [
[0, 1, 1, 0], # A connects to B and C
[0, 0, 0, 1], # B connects to D
[0, 0, 0, 1], # C connects to D
[0, 0, 0, 0], # D has no outgoing edges
]
# Check if edge A→B exists:
if matrix[0][1] == 1: print("A→B exists")
Space: O(V²). O(1) edge lookup. Best for dense graphs.
| Property | Adjacency list | Adjacency matrix |
|---|---|---|
| Space | O(V + E) | O(V²) |
| Edge check | O(degree) | O(1) |
| Add edge | O(1) | O(1) |
| Get all neighbors | O(degree) | O(V) |
| Best for | Sparse, most real graphs | Dense, small graphs |