### Data structures used to represent graphs

• Overview: Data structures used to represent graphs

• Commonly used data structures for graphs:

• Common practice in graph representation

• Mapping

 Nodes in the graph are mapped to integers 0, 1, 2, ..., (n−1)

Example:

• Storing nodes:

• Nodes are represented:

 the index of an one-dimensional array

• Storing edges:

 Edges are stored as a linked list

• Example:

• Graph:

• Representation:

• Class used to represent (define) edges:

 ``` /* ========================================== Edges is stored as Node of a linked list ========================================== */ public class Edge { int NodeID; // The neighbor node Node next; // Link variable } ```

• Class used to represent (define) a graph:

 ``` /* ============================================================= The graph is an array of Edge (Edge[i] = all edges of node i) ============================================================= */ public class Graph { public Edge[] graph; // Array of Edges } ```

• I won't dwell too much on the list representation because the most commonly used representation for graphs is the adjacency array ---- which is discussed next.

• Storing nodes:

• Nodes are represented:

 the index of a two-dimensional array (= matrix)

• Storing edges:

 Edges are represented as a non-zero value in the adjacency matrix (0 means: no edge)

• Example:

• Graph:

• Representation:

 ``` 0 1 2 3 4 5 6 7 8 +- -+ | 0 1 0 1 0 0 0 0 1 | // Node 0 | 1 0 0 0 0 0 0 1 0 | // Node 1 | 0 0 0 1 0 1 0 1 0 | // Node 2 | 1 0 1 0 1 0 0 0 0 | // Node 3 M = | 0 0 0 1 0 0 0 0 1 | // Node 4 | 0 0 1 0 0 0 1 0 0 | // Node 5 | 0 0 0 0 0 1 0 0 0 | // Node 6 | 0 1 1 0 0 0 0 0 0 | // Node 7 | 1 0 0 0 1 0 0 0 0 | // Node 8 +- -+ ```

• Row 0 corresponds to node 0

• Node 0 is adjacent to the nodes: 1, 3 and 8.

• Java class used to represent (define) a graph using an adjacency array:

 ``` /* ======================================= The graph class using adjacency matrix ======================================= */ public class Graph { int[][] M; // M[i][j] > 0 <==> edge (i,j) exists .... (other methods still need to be added) } ```

• Data structure selection

• The selection of a data structure has consequences to the running times of algorithms

• Many algorithms solve problems by traversing all edges in the graph

• Assume that a graph has:

 n nodes m edges

• Running time to visit all edges:

• O(m + n)

Because:

We must:

 Visit each array element: n steps Visit all "edges" (the blue squares): m steps

• O(n2)

Because:

 ``` 0 1 2 3 4 5 6 7 8 +- -+ | 0 1 0 1 0 0 0 0 1 | // 0 | 1 0 0 0 0 0 0 1 0 | // 1 | 0 0 0 1 0 1 0 1 0 | // 2 | 1 0 1 0 1 0 0 0 0 | // 3 M = | 0 0 0 1 0 0 0 0 1 | // 4 | 0 0 1 0 0 0 1 0 0 | // 5 | 0 0 0 0 0 1 0 0 0 | // 6 | 0 1 1 0 0 0 0 0 0 | // 7 | 1 0 0 0 1 0 0 0 0 | // 8 +- -+ ```

We must visit all elements in an n × n matrix

• Note:

 When a graph has a large number of edges, we will have m ~= n × n Then no matter which representation you choose, the running time will be O(n × n)

• Ease of programming- Choice of data structure:

 Adjacency matrix usually result in simpler algorithms because you deal with one data structure (matrix) The Adjacency list is a composite structure with an array and a list (or 2 lists)