Directed vs. Undirected: In an undirected graph, edges have no orientation; the connection is identical to . In a directed graph (or digraph), edges have a specific direction, meaning is a one-way path from to .
Weighted vs. Unweighted: Weighted graphs assign a numerical value (weight) to each edge, representing costs, distances, or capacities. Unweighted graphs treat all connections as equal, effectively having a uniform weight of 1.
Cyclic vs. Acyclic: A cyclic graph contains at least one path that starts and ends at the same vertex. An acyclic graph (like a tree) contains no such paths, ensuring a hierarchical or linear flow of data.
Adjacency Matrix: This is a 2D array of size where the entry at row and column indicates the presence (and weight) of an edge between vertex and vertex . It allows for edge lookups but consumes space, making it inefficient for sparse graphs.
Adjacency List: This representation uses an array of lists, where each index contains a list of all vertices adjacent to vertex . It is space-efficient for sparse graphs, requiring space, though checking for a specific edge takes time.
Edge List: A simple collection of all edges in the graph, usually stored as a list of pairs or triplets (for weighted graphs). While easy to implement, it is inefficient for most graph operations like finding neighbors.
| Feature | Adjacency Matrix | Adjacency List |
|---|---|---|
| Space Complexity | ||
| Edge Lookup | ||
| Finding Neighbors | ||
| Best Use Case | Dense graphs () | Sparse graphs () |
Graph vs. Tree: A tree is a specific type of graph that is connected and acyclic. While all trees are graphs, not all graphs are trees; graphs can have cycles and multiple disconnected components.
Path vs. Cycle: A path is a sequence of vertices where each adjacent pair is connected by an edge and no vertex is repeated. A cycle is a path that starts and ends at the same vertex.
Handshaking Lemma: Always remember that in an undirected graph, the sum of all vertex degrees is exactly twice the number of edges: . This is a frequent tool for calculating edge counts or verifying graph validity.
Complexity Analysis: When choosing a representation, evaluate the graph's density. If the number of edges is close to the square of the number of vertices, the matrix is often superior; otherwise, the list is the standard choice.
Connectivity Checks: For problems involving reachability, consider whether the graph is strongly connected (in directed graphs, every vertex is reachable from every other) or just weakly connected.
Self-loops and Multi-edges: Always check if the problem allows for self-loops (an edge from a vertex to itself) or multiple edges between the same pair of vertices, as these can change the results of algorithms.