A graph is a data structure representing a collection of objects and the relationships between them. Formally, a graph is a pair where:

  • is a set of vertices (also called nodes).
  • is a collection of edges, each connecting a pair of vertices.

Graphs are the most general non-linear structure — trees, lists, and grids are all special cases of graphs. Used for everything from social networks (people = vertices, friendships = edges) to road maps (intersections, roads), web pages (URLs, hyperlinks), and circuit topology.

Example

Airports as a graph: each vertex stores a 3-letter airport code; each edge represents a flight route, possibly weighted with mileage.

Types

Undirected graphs

Edges have no direction — an edge between vertices and is just an unordered pair . If the graph has as an edge, you can traverse from 1 to 2 or 2 to 1.

Directed graphs (digraphs)

Edges have direction — represented as ordered pairs where the edge goes from to . If the graph has as an edge, you can go 1 → 2 but not necessarily 2 → 1.

If both and are edges in a directed graph, you can travel either way.

Weighted graphs

Each edge has a numerical weight (cost, distance, capacity, time). Used for shortest-path problems, network flow, etc. See Dijkstra’s algorithm.

Connectivity

  • Undirected graph is connected if there’s a path between every pair of vertices.
  • Directed graph is strongly connected if there’s a directed path from every vertex to every other vertex.
  • Directed graph is weakly connected if, ignoring edge directions, it’s connected (the underlying undirected graph is connected).

Representation

Two main ways to store a graph in memory:

  • Adjacency matrix — a matrix with entries indicating edges. space, edge lookup. Best for dense graphs.
  • Adjacency list — for each vertex, a list of its neighbors. space, edge lookup. Best for sparse graphs.

Most real-world graphs are sparse — social networks, road graphs, web graphs all have . So adjacency lists dominate practical use. The choice of representation affects algorithm complexity: BFS and DFS run in on a matrix but on a list.

Construction

void create_graph() {
    int n, adj[100][100];
    int count, max_edge, origin, destin;
    
    printf("Enter number of vertices: ");
    scanf("%d", &n);
    
    max_edge = n * (n - 1);
    for (count = 1; count <= max_edge; count++) {
        printf("Enter edge %d (-1 -1 to quit): ", count);
        scanf("%d %d", &origin, &destin);
        if (origin == -1 && destin == -1) break;
        if (origin >= n || destin >= n || origin < 0 || destin < 0) {
            printf("Invalid edge!\n");
            count--;
        } else {
            adj[origin][destin] = 1;
        }
    }
}

This builds an adjacency matrix interactively. The matrix adj[i][j] = 1 indicates an edge from to .

Operations

The fundamental graph operations:

  • Traversal: visit every reachable vertex from a starting point. See Breadth-first search and Depth-first search.
  • Shortest path: find the cheapest route between two vertices. See Dijkstra’s algorithm.
  • Spanning tree: extract a tree that connects all vertices with minimum total edge weight. See Prim’s algorithm.
  • Topological sort, strongly connected components, cycle detection — graph-specific algorithms.

For traversal, see the BFS/DFS notes. For weighted-graph shortest paths, see Dijkstra. For minimum spanning trees, see Prim.