L-8-- DSA Graph
L-8-- DSA Graph
Lecture 7:
Data Structures: Graph
Graph Representation
We can choose between two standard ways to represent a graph G = (V, E) as a collection of
1. Adjacency List: Because the adjacency-list representation provides a compact way to represent sparse
graphs, those for which |E| is much less than |V|2, it is usually the method of choice.
2. Adjacency Matrix: We may prefer an adjacency matrix representation, however, when the graph is dense,
|E| is close to |V|2, or when we need to quickly determine if there is an edge connecting two given vertices.
Either way applies to both directed and undirected graphs.
DSA: Graph => Adjacency List
▪ The adjacency-list representation of a graph G = (V, E) consists of an array Adj of |V| lists, one for
each vertex in V.
▪ For each u ∊ V, the adjacency list Adj[u] contains all the vertices such that there is an edge (u, v) ∊
E. That is, Adj[u] consists of all the vertices adjacent to u in G.
▪ If G is a directed graph, the sum of the lengths of all the adjacency lists is |E|,
▪ An edge of the form (u, v) is represented by appearing in Adj[u].
▪ Moreover, if G is an undirected graph, the sum of the lengths of all the adjacency lists is 2|E|,
since if (u, v) is an undirected edge, then u appears in v’s adjacency list and vice versa.
▪ For directed and undirected graphs, the adjacency-list representation requires Θ(V + E) memory.
1 2 4 /
1 4
V = {1, 2, 3, 4, 5} 2 3 /
3 3 4 /
E = {(1, 2), (1, 4), (2, 3), (3, 4), (4, 5)}
4 5 /
2 5
5 /
DSA: Graph => Adjacency Matrix
▪ For the adjacency-matrix representation of a graph G = (V, E), the vertices are numbered 1, 2,
...., |V| arbitrarily.
▪ Then the adjacency-matrix representation of a graph G consists of a |V| x |V| matrix,
▪ A = (𝑎𝑖𝑗 ) such that if (i, j) ⋴ E, then 𝑎𝑖𝑗 = 1; otherwise, 𝑎𝑖𝑗 = 0.
▪ Since in an undirected graph, (u, v) and (v, u) represent the same edge, the adjacency matrix A of
an undirected graph is its own transpose, A = 𝐴𝑇 .
▪ An adjacency matrix can represent a weighted graph. It is best for dense graphs
1 2 3 4 5
V = {1, 2, 3, 4, 5} 1 4
1 0 1 0 1 0
E = {(1, 2), (1, 4), (2, 3), (3, 4), (4, 5)}
3 2 0 0 1 0 0
3 0 0 0 1 0
2 5
4 0 0 0 0 1
5 0 0 0 0 0
DSA: Graph => Breadth First Search
▪ Breadth-first search (BFS) is used for searching or traversing a graph.
▪ Prim’s minimum spanning tree algorithm and Dijkstra’s single-source shortest-paths algorithm use
BFS’s idea.
▪ Given a graph G = (V, E) and a distinguished source vertex, breadth-first search systematically
explores the edges of G to “discover” every vertex that is reachable from s.
▪ It computes the distance (smallest number of edges) from s to each reachable vertex.
▪ It also produces a “breadth-first tree” with roots that contain all reachable vertices.
▪ For any vertex reachable from s, the simple path in the breadth-first tree from s to v corresponds
to a “shortest path” from s to v in G, that is, a path containing the smallest number of edges.
▪ The algorithm works on both directed and undirected graphs.
DSA: Graph => Breadth First Search
Breadth First Search Pseudocode
BFS(G, s):
for each vertex u ∊ G.V - {s}: while Q != ∅:
u.color = WHITE u = DEQUEUE(Q)
u.d = ∞ for each v ∊ G.Adj[u]:
u.π = NIL if v.color == WHITE:
s.color = GRAY v.color = GRAY
s.d = 0 v.d = u.d + 1
s.π = NIL v.π = u
Q=∅ ENQUEUE(Q, v)
ENQUEUE(Q, s) u.color = BLACK
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 - - -
2 - - -
3 6
3 - - -
4 - - -
5 - - -
6 - - -
7 - - -
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 - - -
2 NIL ∞ WHITE
3 6
3 NIL ∞ WHITE
4 NIL ∞ WHITE
5 NIL ∞ WHITE
6 NIL ∞ WHITE
7 NIL ∞ WHITE
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 GRAY
2 NIL ∞ WHITE
3 6
3 NIL ∞ WHITE
4 NIL ∞ WHITE
5 NIL ∞ WHITE
6 NIL ∞ WHITE
Queue: 1
7 NIL ∞ WHITE
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 GRAY
2 1 1 GRAY
3 6
3 NIL ∞ WHITE
4 NIL ∞ WHITE
5 NIL ∞ WHITE
6 NIL ∞ WHITE
Queue: 2
7 NIL ∞ WHITE
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 GRAY
2 1 1 GRAY
3 6
3 1 1 GRAY
4 NIL ∞ WHITE
5 NIL ∞ WHITE
6 NIL ∞ WHITE
Queue: 2 3
7 NIL ∞ WHITE
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 GRAY
3 6
3 1 1 GRAY
4 NIL ∞ WHITE
5 NIL ∞ WHITE
6 NIL ∞ WHITE
Queue: 2 3
7 NIL ∞ WHITE
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 GRAY
3 6
3 1 1 GRAY
4 NIL ∞ WHITE
5 2 2 GRAY
6 NIL ∞ WHITE
Queue: 3 5
7 NIL ∞ WHITE
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 BLACK
3 6
3 1 1 GRAY
4 NIL ∞ WHITE
5 2 2 GRAY
6 NIL ∞ WHITE
Queue: 3 5
7 NIL ∞ WHITE
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 BLACK
3 6
3 1 1 GRAY
4 3 2 GRAY
5 2 2 GRAY
6 3 2 GRAY
Queue: 5 4 6
7 NIL ∞ WHITE
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 BLACK
3 6
3 1 1 BLACK
4 3 2 GRAY
5 2 2 GRAY
6 3 2 GRAY
Queue: 5 4 6
7 NIL ∞ WHITE
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 BLACK
3 6
3 1 1 BLACK
4 3 2 GRAY
5 2 2 GRAY
6 3 2 GRAY
Queue: 4 6 7
7 5 3 GRAY
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 BLACK
3 6
3 1 1 BLACK
4 3 2 GRAY
5 2 2 BLACK
6 3 2 GRAY
Queue: 4 6 7
7 5 3 GRAY
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 BLACK
3 6
3 1 1 BLACK
4 3 2 BLACK
5 2 2 BLACK
6 3 2 GRAY
Queue: 6 7
7 5 3 GRAY
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 BLACK
3 6
3 1 1 BLACK
4 3 2 BLACK
5 2 2 BLACK
6 3 2 BLACK
Queue: 7
7 5 3 GRAY
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search
1 4 7 1 NIL 0 BLACK
2 1 1 BLACK
3 6
3 1 1 BLACK
4 3 2 BLACK
5 2 2 BLACK
6 3 2 BLACK
Queue:
7 5 3 BLACK
DSA: Graph => Breadth First Trees
The procedure BFS builds a breadth-first tree as it searches the graph. The tree corresponds to the ⲡ attributes. More
formally, for a graph G = (V, E) with source s, we define the predecessor subgraph of G as,
The predecessor subgraph Gⲡ is a breadth-first tree if Vⲡ consists of the vertices reachable from s. For all v ∊ Vⲡ, the
subgraph Gⲡ contains a unique simple path from s to v that is also the shortest path from s to v in G.
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 - - - -
2 - - - -
3 6
3 - - - -
4 - - - -
5 - - - -
6 - - - -
7 - - - -
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL WHITE - -
2 NIL WHITE - -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
5 NIL WHITE - -
6 NIL WHITE - -
7 NIL WHITE - -
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL WHITE - -
2 NIL WHITE - -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
6 NIL WHITE - -
7 NIL WHITE - -
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 NIL WHITE - -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
6 NIL WHITE - -
7 NIL WHITE - -
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 GRAY 2 -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
6 NIL WHITE - -
7 NIL WHITE - -
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 GRAY 2 -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
time = 3 5 2 GRAY 3 -
6 NIL WHITE - -
7 NIL WHITE - -
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 GRAY 2 -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
time = 4 5 2 GRAY 3 -
6 5 GRAY 4 -
7 NIL WHITE - -
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 GRAY 2 -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
time = 5 5 2 GRAY 3 -
6 5 BLACK 4 5
7 NIL WHITE - -
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 GRAY 2 -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
time = 6 5 2 GRAY 3 -
6 5 BLACK 4 5
7 5 GRAY 6 -
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 GRAY 2 -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
time = 7 5 2 GRAY 3 -
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 GRAY 2 -
3 6
3 NIL WHITE - -
4 NIL WHITE - -
time = 8 5 2 BLACK 3 8
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 BLACK 2 9
3 6
3 NIL WHITE - -
4 NIL WHITE - -
time = 9 5 2 BLACK 3 8
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 BLACK 2 9
3 6
3 1 GRAY 10 -
4 NIL WHITE - -
time = 10 5 2 BLACK 3 8
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 BLACK 2 9
3 6
3 1 GRAY 10 -
4 3 GRAY 11 -
time = 11 5 2 BLACK 3 8
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 BLACK 2 9
3 6
3 1 GRAY 10 -
4 3 BLACK 11 12
time = 12 5 2 BLACK 3 8
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL GRAY 1 -
2 1 BLACK 2 9
3 6
3 1 BLACK 10 13
4 3 BLACK 11 12
time = 13 5 2 BLACK 3 8
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Depth First Search
Simulation of Depth First Search
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL BLACK 1 14
2 1 BLACK 2 9
3 6
3 1 BLACK 10 13
4 3 BLACK 11 12
time = 14 5 2 BLACK 3 8
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Depth First Search
Complexity Analysis of Depth-First Search
▪ Initially, looping through the nodes takes Θ(V) time to execute the calls to DFS_Visit.
▪ The procedure DFS_Visit is called exactly once for each vertex v ∊ V since the vertex u on which
DFS_Visit is invoked must be white, and the first thing DFS_Visit does is paint vertex u gray.
▪ During an execution of DFS_Visit(G, v), the loop executes |Adj[v]| times.
▪ Hence, the total cost of DFS_Visit is Θ(E). The running time of DFS is, therefore, Θ(V + E).
DSA: Graph => Depth First Trees
▪ As in BFS, whenever DFS discovers a vertex during a scan of the adjacency list of an already
discovered vertex u, it records this event by setting’s predecessor attribute v.π to u.
▪ Unlike a BFS, whose predecessor subgraph forms a tree, the predecessor subgraph produced by a
DFS may comprise several trees because the search may repeat from multiple sources.
▪ Therefore, we define the predecessor subgraph of a DFS slightly differently from that of a BFS.
We let,
Gⲡ = (V, Eⲡ), where
Eⲡ = {(v.ⲡ, v): v ∊ V and v.ⲡ ≠ NIL}
The predecessor subgraph of a depth-first search forms a depth-first forest comprising several
depth-first trees. The edges in Eⲡ are tree edges.
DSA: Graph => Topological Sort
▪ We can use DFS to perform a topological sort of directed acyclic graph, or a “dag,” as it is
sometimes called.
▪ A topological sort of a dag G = (V, E) is a linear ordering of all its vertices such that if G contains
an edge (u, v), then u appears before v in the ordering.
▪ We can view a topological graph as the ordering of its vertices along a horizontal line, with all
directed edges going from left to right.
▪ Topological sorting is thus different from the usual kind of “sorting”. Many applications use
directed acyclic graphs to indicate precedences among events.
Topological_Sort(G):
call DFS(G) to compute finishing times v.f
for each vertex v
as each vertex is finished, insert it onto the front of a linked list
return the linked list of vertices
DSA: Graph => Topological Sort
Simulation of Topological Sort
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 - - - -
2 - - - -
3 6
3 - - - -
4 - - - -
5 - - - -
6 - - - -
7 - - - -
DSA: Graph => Topological Sort
Simulation of Topological Sort
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL BLACK 1 14
2 1 BLACK 2 9
3 6
3 1 BLACK 10 13
4 3 BLACK 11 12
5 2 BLACK 3 8
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Topological Sort
Simulation of Topological Sort
2 5 Starting Finishing
Vertex Parent Visited
Time Time
1 4 7 1 NIL BLACK 1 14
2 1 BLACK 2 9
3 6
3 1 BLACK 10 13
4 3 BLACK 11 12
5 2 BLACK 3 8
1 3 4 2 5 7 6
6 5 BLACK 4 5
7 5 BLACK 6 7
DSA: Graph => Topological Sort
Topological Sort Running Time
We can perform a topological sort in time Θ(V + E) since a depth-first search takes Θ(V + E)
time and inserting each of the |V| vertices onto the front of the linked list takes O (1) time.
End of Lecture 8 on Graph