0% found this document useful (0 votes)
16 views

L-8-- DSA Graph

Uploaded by

yaminsadik.sy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

L-8-- DSA Graph

Uploaded by

yaminsadik.sy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 50

Data Structures and Algorithms

Lecture 7:
Data Structures: Graph

Dr. Nazmul Shahadat


Assistant Professor
Department of Computer Science
Truman State University, Missouri, USA
DSA: Graph
▪ A graph is a structure consisting of objects in which some pairs of objects are "related."
▪ The objects correspond to mathematical abstractions called vertices (also called nodes or points),
▪ Each related pair of vertices is called an edge (a link or line).

Running Time of Graph Algorithms


o The running time of a graph algorithm on a given graph G = (V, E), where the number of vertices
is |V| (denotes symbol V) and the number of edges is |E| (denotes symbol E).
o We adopt a common notational convention for these parameters.
o Use V and E inside the asymptotic notation (such as O-notation or Θ-notation). For example, the
algorithm runs in time O(VE),” meaning that the algorithm runs in time O(|V||E|).
o This convention makes the running-time formulas easier to read without the risk of ambiguity.
DSA: Graph
Directed & Undirected Graph
1. Directed Graph: A directed graph is a set of connected objects (called vertices or nodes) where all the edges
are directed from one vertex to another. It is sometimes called a digraph or a directed network.
2. Undirected Graph: An undirected graph is a set of connected objects (called vertices or nodes) with
bidirectional edges.

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

2 5 Vertex Parent Distance Visited

1 4 7 1 - - -

2 - - -
3 6
3 - - -

4 - - -

5 - - -

6 - - -

7 - - -
DSA: Graph => Breadth First Search
Simulation of Breadth-First Search

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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

2 5 Vertex Parent Distance Visited

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,

Gⲡ = (Vⲡ, Eⲡ), where


Vⲡ = {v ∊ V: v.ⲡ ≠ NIL} ∪ {s} and Eⲡ = {(v.ⲡ, v): v ∊ Vⲡ - {s}}

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.

Complexity Analysis of BFS Applications


o After initialization, the BFS never whitens a vertex, ensuring that each • Driving directions
vertex is enqueued at most once and, hence, dequeued at most once. • Cheap flight itineraries
o Enqueuing and dequeuing take O(1) time, so their total time is O(V). • Network routing
o Because the procedure scans the adjacency list of each vertex only when
the vertex is dequeued, it scans each adjacency list at most once.
o Since the sum of the lengths of all the adjacency lists is O(E).
o The total running time of the BFS is O(V + E).
DSA: Graph => Depth First Search
▪ The strategy followed by depth-first search is to search “deeper” in the graph whenever possible.
▪ Depth-first search explores edges out of the most recently discovered vertex that still has
unexplored edges leaving it.
▪ Once all edges have been explored, the search “backtracks” to explore edges leaving the vertex
from which it was discovered.
▪ This process continues until we have discovered all vertices from the original source vertex.
▪ If undiscovered vertices remain, the DFS selects one of them as a new source and repeats the
search from that source.
▪ The algorithm repeats this entire process until it has discovered every vertex.
DSA: Graph => Depth First Search
Depth First Search Pseudocode

DFS(G): DFS_Visit(G, u):


for each vertex u ∊ G.V: time = time + 1
u.color = WHITE u.d = time
u.π = NIL u.color = GRAY
time = 0 for each v ∊ G.Adj[u]:
for each vertex u ∊ G.V: if v.color == WHITE:
if u.color == WHITE: v.π = u
DFS_Visit(G, u) DFS_Visit(G, v)
u.color = BLACK
time = time + 1
u.f = time
DSA: Graph => Depth First Search
Simulation of Depth First Search

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 - -

time = 0 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 GRAY 1 -

2 NIL WHITE - -
3 6
3 NIL WHITE - -

4 NIL WHITE - -

time = 1 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 GRAY 1 -

2 1 GRAY 2 -
3 6
3 NIL WHITE - -

4 NIL WHITE - -

time = 2 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 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

You might also like