Back to Graph Theory Series

Part 4: What Is a Graph? Types, Families & Representations

August 30, 2026 Wasil Zafar 25 min read

Everything up to this point was a toolbox. This is where we finally open it: the formal definition of a graph, the vocabulary of walks and degree, the major graph families, and how a graph actually lives inside a computer.

Table of Contents

  1. The Formal Definition of a Graph
  2. Walks, Trails, Paths & Cycles
  3. Graph Families
  4. Degree Theory & the Handshaking Lemma
  5. Subgraphs & Graph Operations
  6. Graph Representations
  7. Exercises
  8. Conclusion & Next Steps

The Formal Definition of a Graph

A graph is a pair \(G = (V, E)\), where \(V\) is a set of vertices (or nodes) and \(E\) is a set of edges, each edge being an unordered pair \(\{u, v\}\) of vertices for an undirected graph (or an ordered pair \((u,v)\) for a directed graph, also called a digraph). If \(e = \{u, v\} \in E\), we say \(e\) is incident to \(u\) and \(v\), and that \(u\) and \(v\) are adjacent (neighbors).

Visual Intuition

A Graph Is Really Just “Dots + Connections”

At the most intuitive level, a graph has two ingredients: vertices (the objects) and edges (the relationships between them). The picture below shows how the vocabulary fits together.

1) Vertices and edges Vertices are the dots. Edges are the links joining them. vertex (a node) edge (a connection) A B C D E Example: V = {A, B, C, D, E} and E contains pairs such as {A,B} and {C,E} 2) Adjacency and incidence Two vertices joined by an edge are adjacent. That edge is incident to both endpoints. u v edge e e = {u, v} u and v are adjacent The edge e is incident to both u and v. 3) Same graph, different drawings A graph is an abstract structure. The layout can change while the vertex set and edge set stay the same. Drawing A A B C Same graph same V and same E Drawing B A B C Both drawings represent G = ({A,B,C}, {{A,B}, {B,C}, {A,C}}) Only the placement changes. The adjacency relationships do not.

This is why graph theory focuses on which vertices are connected, not on whether the picture looks geometric, symmetric, or visually "nice." The structure matters; the drawing is just a convenient representation.

Key Insight

A graph is a mathematical object, not a drawing. The same graph \(G = (\{A,B,C\}, \{\{A,B\},\{B,C\},\{A,C\}\})\) can be drawn as a triangle, as three points in a line with curved edges, or in any layout you like — the drawing is a choice, the graph itself is the abstract incidence structure. This distinction matters the moment we discuss planarity in Part 17: "is this graph planar" asks whether some drawing avoids crossings, not whether this particular drawing does.

Directed, Weighted, Simple, and Multigraphs

TypeDefinition
Undirected graphedges are unordered pairs; adjacency is symmetric
Directed graph (digraph)edges (arcs) are ordered pairs; each vertex has an in-degree and out-degree
Mixed graphcontains a combination of both directed and undirected edges
Weighted grapheach edge carries a numeric weight \(w(e)\) (distance, cost, capacity)
Unweighted graphall edges are treated equally with uniform unit cost/weight
Simple graphno self-loops, no repeated edges — the default assumption unless stated otherwise
Multigraphrepeated (parallel) edges between the same pair of vertices are allowed
Pseudographa multigraph that also allows self-loops (edges from a vertex to itself)
Sparse graph\(|E| = O(|V|)\) — most real-world graphs (road networks, social graphs)
Dense graph\(|E|\) is close to the maximum \(\binom{|V|}{2}\)
Planar graphcan be drawn on a 2D plane such that no two edges cross each other
Non-planar graphcannot be drawn on a 2D plane without edge crossings (e.g., \(K_5\) or \(K_{3,3}\))
Connected graphthere exists a path between every pair of vertices
Disconnected graphcontains two or more isolated subgraphs (connected components) with no edges between them
Underlying graphthe undirected simple graph created by replacing all directed/parallel edges with single undirected edges
Visual Intuition

Same Vertices, Different Rules for the Edges

A graph's type tells us what information an edge carries and which edge patterns are allowed. The four pictures below use nearly the same vertices so the difference comes entirely from the edges.

Directed graph An edge has a direction: A → B is not the same as B → A. ABC Ask: “Which way am I allowed to travel?” Weighted graph Edges carry values such as distance, cost, time, or capacity. 472 ABC Ask: “How expensive is each connection?” Simple graph At most one edge per pair, and no edge may loop back to itself. ABC one A–B edge ✓ parallel edge ✗ loop ✗ Multigraph / pseudograph Parallel edges are allowed; a pseudograph may also contain self-loops. AB parallel edge #1 parallel edge #2 self-loop

Quick Mental Test

Directed? Look for arrows. Weighted? Look for numbers or costs on edges. Simple? Check that there are no loops or duplicate edges. Multigraph? Look for two or more distinct edges joining the same pair of vertices.

In a digraph, a vertex \(v\) with in-degree 0 is a source; one with out-degree 0 is a sink. An isolated vertex with both in-degree and out-degree 0 is an isolated node, while a vertex adjacent to every other vertex in an undirected graph is a universal vertex (or dominant vertex). These show up constantly once we study directed acyclic graphs (DAGs) in Part 7 and network flow in Part 14.

Walks, Trails, Paths & Cycles

These terms are easy to conflate, but the exact structural restrictions on repeated vertices or edges matter for major theorems (e.g., Eulerian circuits require closed trails; Hamiltonian cycles require simple paths; network flow relies on augmenting paths):

  • Walk: any sequence of vertices \(v_0, v_1, \dots, v_k\) where consecutive vertices are adjacent. Vertices and edges may repeat freely.
  • Closed walk: a walk that starts and ends at the same vertex (\(v_0 = v_k\)).
  • Open walk: a walk that starts and ends at different vertices (\(v_0 \neq v_k\)).
  • Trail: a walk with no repeated edge (vertices may still repeat).
  • Circuit: a closed trail (no repeated edges, but starts and ends at the same vertex).
  • Eulerian trail: a trail that visits every edge of the graph exactly once.
  • Eulerian circuit: a closed trail (circuit) that visits every edge of the graph conditions-free and returns to the start.
  • Path (simple path): a walk with no repeated vertex (and hence no repeated edge either).
  • Hamiltonian path: a simple path that visits every vertex of the graph exactly once.
  • Cycle: a closed path — no repeated vertices except that the first vertex equals the last (\(v_0 = v_k\)).
  • Hamiltonian cycle: a closed path (cycle) that visits every vertex of the graph exactly once and returns to the start.
  • Girth: the length of the shortest cycle in a graph (defined as \(\infty\) if the graph has no cycles).
  • Circumference: the length of the longest cycle in a graph.
  • Distance \(d(u,v)\): the length (number of edges) of the shortest path connecting \(u\) and \(v\).
  • Diameter: the maximum distance \(d(u,v)\) over all connected pairs of vertices in a graph.
  • Radius: the minimum eccentricity among all vertices (where eccentricity is a vertex's max distance to any other vertex).
Visual Intuition

What Is Allowed to Repeat?

The easiest way to separate these terms is to track vertices and edges independently. A walk is unrestricted; a trail forbids repeated edges; a path forbids repeated vertices; a cycle is a path that closes back at its start.

Walk Vertices and edges may repeat. A → B → C → B → D ABCD B and edge B–C are used again ✓ valid walk    ✗ not a trail Trail Edges cannot repeat; vertices still may. A → B → C → A → D → C ABCD A and C repeat, but every edge is new ✓ valid trail    ✗ not a path Path No vertex repeats, so no edge can repeat either. A → B → C → D ABCD Every visited vertex is new ✓ path ⇒ automatically a trail ⇒ automatically a walk Cycle A path that returns to its starting vertex. A → B → C → D → A ABCD Only the start vertex is repeated — at the end

The Containment Hierarchy

Every path is a trail, and every trail is a walk, but the converses are not true. For closed versions, a cycle is a particularly strict circuit, and a circuit is a closed walk.

Graph Families

A handful of named graph families reappear throughout the entire series as building blocks, extremal examples, and counterexamples.

FamilyNotationDefinition
Complete graph\(K_n\)every pair of the \(n\) vertices is adjacent — \(\binom{n}{2}\) edges
Path graph\(P_n\)\(n\) vertices in a line, each adjacent only to its immediate neighbor(s)
Cycle graph\(C_n\)\(P_n\) with the two ends joined — every vertex has degree 2
Wheel graph\(W_n\)a cycle \(C_{n-1}\) connected to a central universal hub vertex (\(n\) vertices total)
Star graph\(K_{1,n-1}\)one center vertex adjacent to \(n-1\) leaves; leaves not adjacent to each other
Regular graph\(k\)-regularevery vertex has the same degree \(k\)
Strongly regularsrg\((v, k, \lambda, \mu)\)\(k\)-regular, every adjacent pair shares \(\lambda\) common neighbors, non-adjacent share \(\mu\)
Bipartite graph\(G = (V_1 \cup V_2, E)\)\(V\) splits into two sets with all edges crossing between them, none within
Complete bipartite\(K_{m,n}\)bipartite, and every cross-pair is an edge
Complete \(k\)-partite\(K_{n_1, n_2, \dots, n_k}\)vertices split into \(k\) independent sets with all cross-partition edges present
Turán graph\(T(n, r)\)complete \(r\)-partite graph on \(n\) vertices with balanced partition sizes
Tree—connected and acyclic (formalized fully in Part 11)
Forest—a disjoint union of trees (acyclic, possibly disconnected)
DAG—directed, acyclic — models dependencies (Part 7)
Planar graph—can be drawn in the plane with no edge crossings (Part 17)
Outerplanar graph—planar graph that can be drawn such that all vertices lie on the outer face
Platonic graphs—skeletons of the 5 regular convex polyhedra: Tetrahedral, Octahedral, Cube (\(Q_3\)), Icosahedral, Dodecahedral
Hypercube graph\(Q_d\)\(2^d\) vertices represented as binary strings of length \(d\); adjacent if strings differ by 1 bit
Line graph\(L(G)\)represents adjacency between the edges of \(G\) (edges of \(G\) become vertices of \(L(G)\))
Complement graph\(\overline{G}\)same vertex set \(V\), but contains an edge \((u,v)\) iff that edge is not in \(G\)
Self-complementary—a graph that is isomorphic to its own complement
Symmetric graph—vertex-transitive and edge-transitive (e.g., the Petersen graph)
Chordal graph—every cycle of length \(\ge 4\) has a chord (an edge connecting two non-consecutive vertices of the cycle)
Interval graph—intersection graph of a family of intervals on the real line
Visual Reference

Recognize the Family by Its Shape

Named graph families are reusable structural patterns. The parameter in the notation usually controls the number of vertices or the partition sizes; the defining connection pattern stays the same.

Complete graph K₅ Every pair of vertices is adjacent. Dense: 5 vertices, 10 edges Path graph P₅ A single chain with two endpoints. Endpoints have degree 1 Internal vertices have degree 2 Cycle graph C₅ A path whose two ends are joined. Every vertex has degree 2 Wheel graph W₆ A cycle plus one universal hub. hub Hub touches every rim vertex Star graph K₁,₄ One center joined to independent leaves. center Leaves have no edges between them Complete bipartite K₂,₃ Every left vertex connects to every right vertex. set of 2 set of 3

Bipartite Graphs and Trees

Preview: The Odd-Cycle Characterization

A graph is bipartite if and only if it contains no odd-length cycle. One direction is easy (any cycle in a bipartite graph must alternate between the two sides, forcing even length); the other direction — that no odd cycle guarantees a valid 2-coloring exists — is proven constructively with BFS in Part 5, once we have the traversal machinery to actually 2-color the graph layer by layer.

Bipartite Graphs & The Odd-Cycle Characterization A graph is 2-colorable if and only if it contains no odd-length cycles. Trees are intrinsically bipartite. EVEN CYCLE (C₄) Valid 2-Coloring Set U (Color 1) Set V (Color 2) u₁ v₁ v₂ u₂ Cycle Length = 4 (Even). Edges strictly alternate between Set U and Set V. ODD CYCLE (C₃) Monochromatic Conflict! Set U (Color 1) Set V (Color 2) u₁ v₁ u₂? SAME SET EDGE! Cycle Length = 3 (Odd Triangle). Forced edge between two nodes in the same partition set! Why All Trees are Bipartite (2-Colorable) Trees contain no cycles at all, naturally satisfying the odd-cycle condition. Color layer-by-layer using Breadth-First Search (BFS): L₀ L₁ L₁ L₂ L₂ Even Depths → Set U Odd Depths → Set V ✓ Guaranteed 0 Conflicts

Degree Theory & the Handshaking Lemma

The degree \(\deg(v)\) of a vertex is the number of edges incident to it (a self-loop, in a pseudograph, counts twice). The sequence of all vertex degrees, usually sorted, is the degree sequence.

$$\textbf{Handshaking Lemma: } \sum_{v \in V} \deg(v) = 2|E|$$

We proved this by double counting in Part 2, and by contradiction (the odd-degree-count corollary) in Part 1. A natural follow-up question: given a sequence of non-negative integers, does some simple graph realize it as a degree sequence? The Erdős–Gallai theorem answers this in general, and the constructive Havel-Hakimi algorithm answers it by actually building such a graph (or proving none exists) — we implement Havel-Hakimi as part of the algorithm deep dives once the batch reaches it.

Subgraphs & Graph Operations

A subgraph \(H\) of \(G\) has \(V(H) \subseteq V(G)\) and \(E(H) \subseteq E(G)\) (with every edge's endpoints still in \(V(H)\)). Two important special cases: an induced subgraph on vertex set \(S \subseteq V\) includes every edge of \(G\) with both endpoints in \(S\); a spanning subgraph keeps all of \(V(G)\) but only some edges. The complement \(\overline{G}\) has the same vertex set with edges exactly where \(G\) has non-edges — a direct application of set complements from Part 1.

Graph Representations

How a graph lives in memory determines an algorithm's complexity. The two workhorse representations:

Adjacency list — a map from each vertex to the list of its neighbors. Space: \(O(V+E)\). Best for sparse graphs and for iterating a vertex's neighbors quickly (most graph algorithms in this series, starting with BFS/DFS in Parts 5–6, use this).

Adjacency matrix — an \(n \times n\) matrix \(A\) with \(A_{ij} = 1\) (or the edge weight) if \(\{i,j\} \in E\). Space: \(O(V^2)\) regardless of edge count, but \(O(1)\) edge-existence checks — ideal for dense graphs and algorithms like Floyd-Warshall (Part 10) that scan all pairs anyway.

from collections import defaultdict

class Graph:
    """Adjacency-list graph. Space: O(V + E)."""

    def __init__(self, directed=False):
        self.adj = defaultdict(list)
        self.directed = directed

    def add_edge(self, u, v, weight=1):
        self.adj[u].append((v, weight))
        if not self.directed:
            self.adj[v].append((u, weight))

    def neighbors(self, u):
        return self.adj[u]

    def degree(self, u):
        return len(self.adj[u])

# Build the 4-cycle A-B-C-D-A
g = Graph(directed=False)
for u, v in [("A", "B"), ("B", "C"), ("C", "D"), ("D", "A")]:
    g.add_edge(u, v)

print("Neighbors of A:", g.neighbors("A"))   # [('B', 1), ('D', 1)]
print("Degree of A:", g.degree("A"))          # 2

# Handshaking Lemma check: sum(deg(v)) == 2 * |E|
total_degree = sum(g.degree(v) for v in "ABCD")
print("Sum of degrees:", total_degree, "== 2 * 4 edges =", 2 * 4)
#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;

class Graph {
    unordered_map<string, vector<pair<string, int>>> adj;
    bool directed;
public:
    Graph(bool isDirected = false) : directed(isDirected) {}

    void addEdge(const string& u, const string& v, int weight = 1) {
        adj[u].push_back({v, weight});
        if (!directed) adj[v].push_back({u, weight});
    }

    vector<pair<string, int>>& neighbors(const string& u) {
        return adj[u];
    }

    int degree(const string& u) {
        return adj[u].size();
    }
};

int main() {
    Graph g(false);
    g.addEdge("A", "B");
    g.addEdge("B", "C");
    g.addEdge("C", "D");
    g.addEdge("D", "A");

    cout << "Degree of A: " << g.degree("A") << endl; // 2

    int totalDegree = 0;
    for (char v : {'A', 'B', 'C', 'D'})
        totalDegree += g.degree(string(1, v));
    cout << "Sum of degrees: " << totalDegree << " == 2 * 4 edges" << endl;
    return 0;
}
import java.util.*;

class Graph {
    private Map<String, List<int[]>> adjIndex = new HashMap<>();
    private Map<String, List<Map.Entry<String, Integer>>> adj = new HashMap<>();
    private boolean directed;

    public Graph(boolean directed) { this.directed = directed; }

    public void addEdge(String u, String v, int weight) {
        adj.computeIfAbsent(u, k -> new ArrayList<>())
           .add(new AbstractMap.SimpleEntry<>(v, weight));
        if (!directed) {
            adj.computeIfAbsent(v, k -> new ArrayList<>())
               .add(new AbstractMap.SimpleEntry<>(u, weight));
        }
    }

    public void addEdge(String u, String v) { addEdge(u, v, 1); }

    public List<Map.Entry<String, Integer>> neighbors(String u) {
        return adj.getOrDefault(u, new ArrayList<>());
    }

    public int degree(String u) { return neighbors(u).size(); }

    public static void main(String[] args) {
        Graph g = new Graph(false);
        g.addEdge("A", "B");
        g.addEdge("B", "C");
        g.addEdge("C", "D");
        g.addEdge("D", "A");

        System.out.println("Degree of A: " + g.degree("A")); // 2

        int totalDegree = 0;
        for (String v : new String[]{"A", "B", "C", "D"})
            totalDegree += g.degree(v);
        System.out.println("Sum of degrees: " + totalDegree + " == 2 * 4 edges");
    }
}

Edge List, Incidence Matrix, and CSR

Three more representations matter in specific contexts:

  • Edge list: just a flat list of \((u, v, w)\) triples. Space \(O(E)\). Ideal input format for Kruskal's algorithm (Part 11), which sorts edges globally by weight.
  • Incidence matrix: an \(|V| \times |E|\) matrix where entry \((v, e)\) is nonzero iff vertex \(v\) is an endpoint of edge \(e\). This is the matrix whose column space underlies the cut space from Part 3.
  • Compressed Sparse Row (CSR): the production-grade format for huge sparse graphs — a flat array of all neighbors (concatenated) plus an offset array marking where each vertex's neighbor block starts. This avoids the pointer-chasing overhead of a Python-style adjacency list and is what high-performance graph libraries (and GPUs) actually use internally.

Choosing a Representation

Rule of thumb for the rest of this series: use an adjacency list by default (BFS, DFS, Dijkstra, Kruskal all prefer it); switch to an adjacency matrix only when the graph is dense or the algorithm needs \(O(1)\) edge lookups over all pairs (Floyd-Warshall); reach for an edge list when an algorithm's first step is "sort all edges" (Kruskal's).

Exercises

  1. Draw \(K_5\), \(C_5\), and \(K_{2,3}\). Verify \(|E(K_5)| = \binom{5}{2} = 10\).
  2. Give an example of a walk that is not a trail, a trail that is not a path, and explain why every path is automatically a trail.
  3. Prove that a graph is bipartite if it is a tree (hint: 2-color the tree using BFS layers, then show adjacent vertices always land in different layers — you can take this on faith for now; we prove it rigorously in Part 5).
  4. Write out the degree sequence of \(K_{3,3}\), and verify the Handshaking Lemma holds.
  5. Challenge: Implement the adjacency-matrix representation in your language of choice, and write a function that converts it to an adjacency list in \(O(V^2)\) time. Then argue why converting the other direction (list → matrix) is also \(O(V^2)\), even though the list itself only takes \(O(V+E)\) space.

Conclusion & Next Steps

Graph theory now has its formal footing: the definition of \(G = (V,E)\), the walk/trail/path/cycle hierarchy, the major named graph families, degree theory and the Handshaking Lemma, subgraphs and basic operations, and every representation you'll implement algorithms against. Everything from here on is genuinely about graphs.

Next in the Series

In Part 5: Graph Traversal I — Breadth-First Search, we put BFS's shortest-path guarantee to work testing bipartiteness, finding connected components, and crawling the web.