10. Graphs
Where We Are?
Tree Binary Tree
Heap
Array Linked list
Binary Search Tree
QueueStack
Graph
Graph: Initial Use
Euler Walk Problem [1736]
Starting from a land, is it possible to return to the starting location after walking across each of the bridges exactly once?
A ~ D : landa ~ g : bridge
A ~ D : vertexa ~ g : edge
Pregel River in Könisgberg Graph Representation
A
B
C
D
a b
c d
e
f
g
A
B
C
D
a b
c de
f
g
Graph: Definition
Graph : G = (V, E) where
V(G) : a nonempty set of vertices (or nodes) V
E(G) : a (possible empty) set of edges (or links) (V V)
Undirected Graph : Unordered, i.e., (u, v) = (v, u)
Directed Graph : Ordered, i.e., (u, v) ≠ (u, v)
A
B
C D
E
F
Undirected Graph
A
B
C D
E
F
Directed Graph
Tail in the edge (A, B)
Head in the edge (A, B)
Graph: Examples
G1 : V(G1) = {0, 1, 2, 3}
E(G1) = {(0,1), (0,2), (0,3), (1,2), (1,3), (2,3)}
G2 : V(G2) = {0, 1, 2, 3, 4, 5, 6}
E(G2) = {(0,1), (0,2), (1,3), (1,4), (2,5), (2,6)}
G3 : V(G3) = {0, 1, 2}
E(G3) = {(0,1), (1,0), (1,2)}
Graph: G1
0
1
3
2
G2
0
1
3 4
2
5 6
Graph: G2
0
1
2
Graph: G3
Graph: Applications in Real-World
Graph Vertex Edge
Networks Computer Cable
Circuits Chip Line
Transportation City Road
Waterworks Plant Pipe
Internet Web page Hyper link
Molecular Structure Molecule Connection
Economy Stocks Transactions
Graph: Terminology Adjacent
If (u, v) is an edge in E(G), then the vertices u and v are adjacent
Moreover, we say that the edge (u, v) is incident on vertices u and v.
Degree (of a vertex v)
The number of edges incident to the vertex v
If G is a Directed graph
In-degree: Number of edges for which v is the head
Out-degree: Number of edges for which v is the tail
Grap
h: G
1
0
1
2
Graph: G2
• Vertices {0, 5, 6} are adjacent to vertex 2
• Degree of vertex 2 is 3
• Edge (2, 6) is incident on vertices 2 & 6
• Vertex 1 has in-degree 1, out-degree
2, and degree 3
G2
0
1
3 4
2
5 6 • Vertex 2 (1) is adjacent from (to) vertex 1 (2)
• Edges (0, 1) and (1, 0) are incident to vertices 0 & 1
Graph: Terminology
Path (from vertex u and vertex v)
A sequence of vertices u, i1, i2,…, ik, v, such that (u,i1), (i1,i2),…, (ik,v) E(G)
Cycle
A simple path where the first and last vertices are the same.
Connected Graph (cf., Disconnected Graph)
A graph that has a path between every pair of distinct vertices
Vertices u and v are said to (strongly) be connected iff there is a path between them
Cf., A connected component is a maximal connected subgraph
Grap
h: G
1
• A path from 0 to 6 is 0, 2, 6
G2
0
1
3 4
2
5 6
• A path 0, 1, 4, 0 is a cycle
0
2 4
1
3
Graph: G2
Connected component
Connected Graph
Acyclic Graph
A graph that has no cycle
Tree
A connected acyclic graph
Subgraph of G: G’
A graph G’ : V(G’) V(G) and E(G’) E(G)
Graph: Terminology
0
1
3 4
2
G2
0
1
3 4
2
5 6
0
1
2
Graph: G3
0
0
1
1
2
0
1
2
Graph: G1 Graph: G2
Some Subgraphs of G3
No cycleConnected & Acyclic
Graph Implementation: Use of Array
Adjacency Matrix
Two-dimensional Array: A(n, n) where n is the number of vertex
A(i, j) = 1 if vertex i and j is adjacent= 0 otherwise
A
B
C D
E
F
Undirected Graph
0 1 0 0 0 0
1 0 1 0 1 0
0 1 0 1 1 0
0 0 1 0 1 0
0 1 1 1 0 1
0 0 0 0 1 0
A B C D E F
A
B
C
D
E
F
A
B
C D
E
F
Directed Graph
0 1 0 0 0 0
0 0 1 0 1 0
0 0 0 1 0 0
0 0 0 0 0 0
0 0 1 1 0 1
0 0 0 0 0 0
A B C D E F
A
B
C
D
E
F
Adjacency Matrix
Memory Space
Directed Graph: Total n2 spaces are required
Undirected Graph: n2/2 spaces are needed because it’s enough to store the half of matrix
Time Complexity
Finding a vertex adjacent to a certain vertex
Computing the degree of a certain vertex
Row or Column sum: Undirected Graph,
Row sum: Out-degree for Directed Graph
Column sum: In-degree for Directed Graph
Thus, it becomes O(n)
A
B
C D
E
F
Undirected Graph
0 1 0 0 0 0
1 0 1 0 1 0
0 1 0 1 1 0
0 0 1 0 1 0
0 1 1 1 0 1
0 0 0 0 1 0
A B C D E F
A
B
C
D
E
F
Degree 3
Graph Implementation: Linked List
Adjacency List
Each vertex i creates a linked list as follows:(where no. of linked lists is no. of nodes)
Each node consists of (vertex, link)
Each linked list i connects all nodes that are adjacent to it
Graph: G1
0
1
3
2
0
1
2
Graph: G3
Head
[0]
[1]
[2]
[3]
1
vertex link
2 3
NU
LL
0 2 3
NU
LL
0 1 3
NU
LL
0 1 2
NU
LL
Head
[0]
[1]
[2]
vertex link
1N
ULL
0 2
NU
LL
NU
LL
Memory Space
Directed graph: Total (n + e) nodes are required(where n is no. of vertex, e is no. of edges)
Undirected graph: Total (n + 2e) nodes are needed(because 2 nodes are used for representing 1 edge)
Adjacency Matrix vs. Adjacency List
Space comparison : O(n2) vs. O(n+e)
Adjacency matrix is useful for dense graphs (i.e., many edges)
Adjacency list is efficient in sparse graphs (i.e., small edges)
Adjacency List
i
j
[i]
…
[j]
j…
i…
i
j
[i]
…
[j]
j…
…
We want to visit all vertices in G that is reachable from a vertex v.
Cf.) Tree traversals: Inorder, Preorder, Postorder
Many problems can be solved using a graph traversal.
Is there a path from one vertex to another?
Is the graph connected?
Find a spanning tree.
Find an articulation point
Two commonly used methods
Breadth First Search (BFS)
Depth First Search (DFS)
Graph Traversal
A
B
C D
E
FH
G
I
Path from A to F?Spanning Tree?
Connected?
Graph Traversal
DFS vs. BFS
DFS is related to Stack, BFS is connected to Queue
DFS: a generalized PREORDER traversal (VLR)
BFS: a generalized LEVEL-ORDER traversal
DFS & BFS should not visit any visited vertex
Use a Flag vector: indicate “visited” if an array element is TRUE
F F T F T F … F
0 1 2 3 4 5 … N-1Visited[ ]
Mark FALSE (Unvisited)
Mark TRUE (Visited)
2 3
4
5
4
2
Depth First Search (DFS)
DFS (v) {
Mark vertex v as visited.
For (each unvisited vertex u adjacent from v)
DFS (u);
}
Main Principle
From the current vertex v, we always visit a vertex adjacent from v
Operational Procedures
Visit a start vertex v by calling DFS(v)
Recursively call DFS at the next unvisited descendant
Example: DFS
1. Start at vertex 1 by calling DFS
2. Mark vertex 1 (as visited) and call DFS at either 2 or 4 (Let’s select vertex 2)
3. Mark vertex 2 (as visited) and call DFS at either 3, 5, or 6 (Let’ select vertex 5)
4. Mark vertex 5 (as visited) and call DFS at either 3, 7, or 8 (Let’s select vertex 8)
5. Keep going on… Final DFS order: 1, 2, 5, 8, 9, 6, 4, 7, 3
2
1
4
6
8
9
7
5
3
1
2
5 8
9
6
4
7
3
Start!
2G[1] 4
NU
LL
1G[2] 5 3 6
NU
LL
DFS : Implementation
Process all descendents of a vertex before we move to an adjacent vertex.
1. Push the first node into the stack & mark it as ‘visited’
2. Repeat until the stack is empty
- Pop a vertex from the top of stack
- get a adjacecy list
- if already visited, skip the vertex
- otherwise,Mark/Visit the vertex as ‘visited’Push all of its adjacent vertices to stack
2 3
4
5
4
2
stack
… 13
3
4
2
4
5
Visited!
We are here!
Now, we are here!
DFS : Implementation
void DFS (int v) { /* v is the start vertex */
node_ptr w;
visited [v] = TRUE; /* indicate that v is visited */
print (v); /* print out the vertex v */
for (w = graph [v]; w; w = w -> link)
/* as to vertex w adjacent to vertex v */
if (visited [w -> vertex] == FALSE )
/* check whether vertex w was visited */
DFS (w -> vertex);
/* if no, call the same DFS() at vertex w */
}
Stack is created by the recursive function calls!
v x
y
z
v
x
gra
ph[v
]
v
gra
ph[x
]
y z
NU
LL
x
v x y
DFS(v) DFS(w->vertex)
u
y
NU
LL
u
y
u
Breadth First Search (BFS)
Main Principle
From current vertex v, always first visit all vertices adjacent to v
Operational Procedures
Visit a start vertex and insert it into a FIFO queue.
Repeatedly delete a vertex from the queue and visit its unvisited adjacent vertices, and insert newly visited vertices into the queue.
Example: BFS
1. Mark vertex 1 (as visited) and insert it into a FIFO queue.
2. Delete 1 from the queue; Mark/Visit its adj. unvisited vertices 2 & 4 and insert them into the queue
3. Delete 2 from the queue;Mark/Visit its adj. unvisited vertices 3, 5, 6 and insert them into the queue
4. Keep going on… Final BFS order: 1, 2, 4, 5, 3, 6, 7, 8, 9
2
1
4
6
8
9
7
5
3
1
Start!
2G[1] 4
Queue
124
2
4
5
53
3
6
6
Queue
536
7
7
8
8
9
9
Finished!
NU
LL
BFS : Implementation
Process all adjacent vertices of a vertex before going to the next level
1. Enqueue the first node into the queue
2. Repeat until the queue is empty
- Dequeue a vertex (at the front of queue)
- Get a adjacency list
- If a vertex was already visited, skip the vertex
- Mark/Visit the vertex as ‘visited’
- Enqueue all of adjacent vertices
BFS : Implementation
void BFS (int v) { /* v is the start vertex */
node_ptr w;
visited [v] = TRUE; /* v is visited */
print (v); /* print out the vertex v */
enqueue (v);
while ( queue ) {
v = dequeue( );
for ( w = graph[v]; w; w->link )
if (visited [w -> vertex] == FALSE )
print ( w->vertex );
enqueue( w->vertex );
visited[w->vertex]=TRUE;
}
v x
y
z
v
gra
ph[v
]gra
ph[x
]
x
v x y
We are here!
Now, we are here!
u
u
Queue
uv xy
y
z
z
z
u x y
NU
LL
v y z
NU
LL
AOV Network
AOV (Activity-On-Vertex) Network
Directed graph
Each vertex represents a task or an activity to be performed
Each edge represents precedence relation between tasks;
Edge<i, j> means that the task i should be performed prior to the task j,
where i is called ‘predecessor’, j is referred to as ‘successor’
E.g., Courses and prerequisites needed for computer science
Number Name Prerequisites
C1 Programming None
C2 Discrete Math. None
C3 Data Structures C1, C2
C4 Calculus None
C5 Linear Algebra C4
C6 Algorithm C3 C5
C1
C3
C4 C5
C6
C2
C3 cannot be started until C1 and C2 have been completed!
C1
C2
C3
i j
Topological Sort
Topological Sort
A linear ordering of vertices in an AOV network such that,
for any two vertices i and j, i precedes j (i.e., i is a predecessor of j)
A vertex that has no predecessor is printed out first.
If every vertex has its predecessor(s), cycles exist! ☞Impossible!
All the vertices may not be compared each other;
thus, several possible topological orders exist! ☞ called ‘partial order’
In ‘courses and prerequisites’, there are several possible topological orders;
{C1, C2, C4, C3, C5, C6}, {C4, C2, C1, C5, C3, C6}, …
C1
C3
C4 C5
C6
C2
C1
C2
C4
C3
C5
C6
C precedes D
C DS … …
Sorting = {S, …, C, D, …}
No predecessor
C
D
A
B
Cycle!
Topological Sort
Topological Sort
Input : Directed graph G; Output : Sorted List
for (i = 0; i < n; i++) {
if (every vertex has a predecessor) {
print (”network has a cycle”);
return;
}
pick a vertex v that has no predecessors;
output v;
delete v and all edges leading out of v from G;
}
D
C
A
B
No predecessor
B C DA
No predecessor
No predecessor
Topological Sort : Example
TS Result: V0, V3, V2, V5, V1, V4
(a) initial
V2
V3
V0
V1
V5
V4V0
(b) V0 deleted
V2
V3
V1
V5
V4
V1
V2
V3
(c) V3 deleted
V2
V1
V5
V4
(d) V2 deleted
V1
V5
V4
(d) V5 deleted
V1
V4
(f) V1 deleted
V4
(g) V4 deleted
V1
V2
V1
V5
V1
V4