Chapter 7: Graphs: - Terminology - Storage Structures - Operations and Algorithms - Other Well-Known Problems
Chapter 7: Graphs: - Terminology - Storage Structures - Operations and Algorithms - Other Well-Known Problems
• Terminology
• Storage structures
• Operations and algorithms
• Minimum spanning trees
• Shortest paths
• Other well-known problems
1
Graphs
• Each node may have multiple
predecessors as well as multiple
successors.
2
Terminology
verte A verte A
x x
arcs edge
B E B E
F F
C D C D
Directed Undirected
graph graph
3
Terminology
• Adjacent vertices: there exists an edge that
directly connects them.
4
Graph Storage Structures
• Adjacency matrix
A B C D E
A F0 1 0 0 0 0
A A
B B 0 0 1 0 1 0
C C 0 0 0 1 1 0
B E
D 0 0 0 0 0 0
D
0 0 0 1 0 1
F E E
0 0 0 0 0 0
F F
C D
verte adjacency
x matrix
vector
5
Graph Storage Structures
• Adjacency matrix
A B C D E
A F0 1 0 0 0 0
A A
B B 1 0 1 0 1 0
B E C C 0 1 0 1 1 0
D 0 0 1 0 1 0
F D
0 1 1 1 0 1
E E
0 0 0 0 1 0
C D F F
verte adjacency
x matrix
vector
6
Graph Storage Structures
• Adjacency List
A A B
B A C E
B E C B D E
F D C E
C D E B C D F
F E
verte adjacency
x list 7
vector
Graph Data Structure
count first
graphHea
d
B A C E
dest nextArc
graphArc
8
Graph Data Structure
graphHead graphArc
count <integer> dest <pointer to
graphVertex>
first <pointer to graphVertex> nextArc <pointer to
graphArc>
end graphHead end graphArc
graphVertex
nextVertex <pointer to graphVertex>
data <data type>
inDegree <integer>
outDegree <integer>
processed <0, 1, 2>
arc <pointer to graphArc> 9
Operations
• Insert vertex
• Delete vertex
• Insert arc/edge
• Delete arc/edge
• Traverse graph
10
Create Graph
Algorithm createGraph (ref graph <metadata>)
Initializes the metadata elements of a graph structure
Pre graph is metadata structure
Post metadata elements have been initialized
1 count = 0
2 first = null
End createGraph
11
Insert Vertex
Algorithm insertVertex (ref graph <metadata>,
val dataIn <dataType>)
Allocates memory for a new vertex and copies the data to it
Pre graph is a graph head structure
dataIn contains data to be inserted into vertex
Post new vertex allocated and data copied
Return +1 if successful
−1 if memory overflow
12
Insert Vertex
1 allocate (newPtr)
2 if (allocation not successful)
1 return −1
3 else
Initializes the new vertex
1 newPtr -> nextVertex = null
2 newPtr -> data = dataIn
3 newPtr -> inDegree = 0
4 newPtr -> outDegree = 0
5 newPtr -> processed = 0
6 newPtr -> arc = null
7 graph.count = graph.count + 1
13
Insert Vertex
8 locPtr = graph.first
9 if (locPtr = null)
Empty graph. Insert at the beginning
1 graph.first = newPtr
10 else
1 predPtr = null
2 loop (locPtr ≠ null AND dataIn.key > locPtr -> data.key)
1 predPtr = locPtr
2 locPtr = locPtr -> nextVertex
3 if (predPtr = null)
1 graph.first = newPtr
else
1 predPtr -> nextVertex = newPtr
4 newPtr -> nextVertex = locPtr
11 return +1
End insertVertex 14
Delete Vertex
Algorithm deleteVertex (ref graph <metadata>,
val key <keyType>)
Deletes an existing vertex only if its degree is 0
Pre graph is a graph head structure
key is the key of the vertex to be deleted
Post vertex deleted
Return +1 if successful
−1 if degree ≠ 0
−2 if key not found
15
Delete Vertex
1 if (graph.first = null)
1 return −2
Locate vertex to be deleted
2 predPtr = null
3 locPtr = graph.first
4 loop (locPtr ≠ null AND key > locPtr -> data.key)
1 predPtr = locPtr
2 locPtr = locPtr -> nextVertex
5 if (locPtr = null OR key ≠ locPtr -> data.key)
1 return −2
16
Delete Vertex
Found vertex to be deleted. Test degree.
6 if (locPtr -> inDegree > 0 OR locPtr -> outDegree > 0)
1 return −1
OK to delete vertex.
7 if (predPtr = null)
1 graph.first = locPtr -> nextVertex
8 else
1 predPtr -> nextVertex = locPtr -> nextVertex
9 graph.count = graph.count − 1
10 recycle (locPtr)
11 return +1
End deleteVertex 17
Insert Arc
Algorithm insertArc (ref graph <metadata>,
val fromKey <keyType>,
val toKey <keyType>)
Add an arc between two vertices
Pre graph is a graph head structure
fromKey is the key of the source vertex
toKey is the key of the destination vertex
Post arc added to adjacency list
Return +1 if successful
−1 if memory overflow
−2 if fromKey not found
−3 if toKey not found 18
Insert Arc
1 allocate (newArcPtr)
2 if (allocation not successful)
1 return −1
Locate source vertex
3 fromPtr = graph.first
4 loop (fromPtr ≠ null AND fromKey > fromPtr -> data.key)
1 fromPtr = fromPtr -> nextVertex
5 if (fromPtr = null OR fromKey ≠ fromPtr -> data.key)
1 return −2
19
Insert Arc
Locate destination vertex
6 toPtr = graph.first
7 loop (toPtr ≠ null AND toKey > toPtr -> data.key)
1 toPtr = toPtr -> nextVertex
8 if (toPtr = null OR toKey ≠ toPtr -> data.key)
1 return −3
Insert new arc
9 fromPtr -> outDegree = fromPtr -> outDegree + 1
10 toPtr -> inDegree = toPtr -> inDegree + 1
11 newArcPtr -> dest = toPtr
20
Insert Arc
12 if (fromPtr -> arc = null)
Inserting first arc
1 fromPtr -> arc = newArcPtr
2 newArcPtr -> nextArc = null
3 return +1
13 else
Find insertion point in adjacency list
1 arcPredPtr = null
2 arcWalkPtr = fromPtr -> arc
3 loop (arcWalkPtr ≠ null AND toKey > arcWalkPtr -> dest ->
data.key)
1 arcPredPtr = arcWalkPtr
2 arcWalkPtr = arcWalkPtr -> nextArc 21
Insert Arc
14 if (arcPredPtr = null)
Insertion before first arc
1 fromPtr -> arc = newArcPtr
15 else
1 arcPredPtr -> nextArc = newArcPtr
17 newArcPtr -> nextArc = arcWalkPtr
16 return +1
End insertArc
22
Delete Arc
Algorithm deleteArc (ref graph <metadata>,
val fromKey <keyType>,
val toKey <keyType>)
Add an arc between two vertices
Pre graph is a graph head structure
fromKey is the key of the source vertex
toKey is the key of the destination vertex
Post arc added to adjacency list
Return +1 if successful
−2 if fromKey not found
−3 if toKey not found
23
Delete Arc
1 if (graph.first = null)
1 return −2
Locate source vertex
3 fromVertex = graph.first
4 loop (fromVertex ≠ null AND fromKey > fromVertex ->
data.key)
1 fromVertex = fromVertex -> nextVertex
5 if (fromVertex = null OR fromKey ≠ fromVertex -> data.key)
1 return −2
24
Delete Arc
Locate destination vertex in adjacency list
6 if (fromVertex -> arc = null)
1 return −3
7 prePtr = null
8 arcPtr = fromVertex -> arc
9 loop (arcPtr ≠ null AND toKey > arcPtr -> dest -> data.key)
1 predPtr = arcPtr
2 arcPtr = arcPtr -> nextArc
10 if (arcPtr = null OR toKey < arcPtr -> dest -> data.key)
1 return −3
25
Delete Arc
Delete arc
11 fromVertex -> outDegree = fromVertex -> outDegree − 1
12 toVertex -> inDegree = toVertex -> inDegree − 1
13 if (prePtr = null)
Deleting first arc
1 fromVertex -> arc = arcPtr -> nextArc
14 else
3 prePtr -> nextArc = arcPtr -> nextArc
15 recycle (arcPtr)
16 return +1
End deleteArc
26
Graph Traversal
• Depth-first: all of a vertex's descendents
are processed before an adjacent vertex.
A A X H P E Y M J G
X H Y
G P M J
27
Graph Traversal
A A X H P E Y M J G
X H Y
G P M J
P Y
H E E M M J
A X G G G G G G G
stack
28
Graph Traversal
• Breadth-first: all adjacent vertices are
processed before the descendents of a
vertex.
A A X G H P E M Y J
X H Y
G P M J
29
Graph Traversal
A A X G H P E M Y J
X H Y
G P M J
A X GH HP PE E MY YJ J
queu
e 30
Networks
• Graph whose edges are weighted (weighted
graph).
548
623 B D 320
345 555
C E
467
31
Network Structures
• Adjacency matrix
A B C D E F
A A 0 623 345 0 0 0
B B 623 0 200 54 0 0
8
C C 345 200 0 36 46 0
0 7
D D 0 548 360 0 24 32
5 0
E E 0 0 467 24 0 55
5 5
F F 0 0 0 32 55 0
0 5
verte adjacency
x matrix
vector
32
Network Structures
• Adjacency List
A B 623
F D 320 E 555
verte adjacency
x list
33
vector
Minimum Spanning Tree
• Spanning tree: tree that contains all of the
vertices in a connected graph.
34
Minimum Spanning Tree
• Applications?
35
Minimum Spanning Tree
• There are various algorithms to find the
minimum spanning tree:
e.g. Prim’s
36
5 5
B D 6 B D 3
6 3
2 3 2 F A 2 3 2 F
A
5 3 5
3 C E C E
4 4
5 5
B D 6 B D 3
6 3
2 3 2 F A 2 3 2 F
A
5 3 5
3 C E C E
4 4
5 5
B D 6 B D 3
6 3
2 3 2 F A 2 3 2 F
A
5 3 5
3 C E C E 37
4 4
already in tree
5
B D
A 3 F
C E
4
5
B D
min edge
A 3 F
C X E
4
38
Minimum Spanning Tree
Prim’s algorithm:
Tree = {first vertex} v u
Loop (Tree is not complete)
minWeight = +∞
For every v∈Tree
For every u∉Tree and adjacent(v, u)
If weight(v, u) < minWeight
minWeight = weight(v, u)
minEdge = (v, u)
Add minEdge to Tree
39
Spanning Tree Data Structure
graphHead graphEdge
count <integer> destination <pointer to
graphVertex>
first <pointer to graphVertex> nextEdge <pointer to
graphEdge>
end graphHead inTree <boolean>
weight <integer>
end graphEdge
graphVertex
nextVertex <pointer to graphVertex>
data <data type>
inDegree <integer>
outDegree <integer>
inTree <boolean>
edge <pointer to graphEdge> 40
end graphHead
Algorithm spanningTree (val graph <graphHead>) /* Prim’s algorithm */
Determines the minimum spanning tree of a network
Pre graph is a graph head structure
Post minimum spanning tree determined
1 if (empty graph)
1 return
2 vertexPtr = graph.first
3 loop (vertexPtr not null)
set inTree flag false
1 vertexPtr −> inTree = false
2 edgePtr = vertexPtr −> edge
3 loop (edgePtr not null)
1 edgePtr -> inTree = false
2 edgePtr = edgePtr -> nextEdge
4 vertexPtr = vertexPtr -> nextVertex
Now derive minimum spanning tree
4 vertexPtr = graph.first
5 vertexPtr -> inTree = true
6 treeComplete = false
41
7 loop (not treeComplete)
1 treeComplete = true
2 chkVertexPtr = vertexPtr
3 minEdge = +∝
4 minEdgePtr = null
5 loop (chkVertexPtr not null)
Walk thru graph checking vertices in tree
1 if (chkVertexPtr -> inTree = true AND chkVertexPtr -> outDegree > 0)
1 edgePtr = chkVertexPtr -> edge
2 loop (edgePtr not null)
1 if (edgePtr -> destination -> inTree = false)
1 treeComplete = false
2 if (edgePtr -> weight < minEdge)
1 minEdge = edgePtr -> weight
2 minEdgePtr = edgePtr
2 edgePtr = edgePtr -> nextEdge
2 chkVertexPtr = chkVertexPtr -> nextVertex
6 if (minEdgePtr not null)
Found edge to insert into tree
1 minEdgePtr -> inTree = true
2 minEdgePtr -> destination -> inTree = true
8 return
End spanningTree 42
Shortest Path
• Find the shortest path between any two
vertices in a network.
43
Shortest Path
• Applications?
44
Shortest Path
• There are various algorithms:
45
5 5
B D 6 B D 3
6 3
2 3 2 F A 2 3 2 F
A
5 5
3 C E C E
3 4
4
5 5 5 6
B D B D 3
3
3 2 F A 2 F
A
5 5
C E C E
3 3 4
4
5 6 5 6
B D B D
3 9
F A F
A
5 C E
C E 46
3 7 3 7
Shortest Path
• Select the source vertex
47
Shortest Path
Dijkstra’s algorithm:
Tree = {source vertex} v u
Loop (Tree is not complete)
minPathLen = +∞
For every v∈Tree
minWeight = +∞
For every u∉Tree and adjacent(v, u)
If weight(v, u) < minWeight
minWeight = weight(v, u)
minEdge = (v, u)
If pathLenFrom(v) + minWeight < minPathLen
minPathLen = pathLenFrom(v) + minWeight
shortestPath = pathFrom(v) + minEdge
Add shortestPath to Tree 48
Shortest Path Data Structure
graphHead graphEdge
count <integer> destination <pointer to
graphVertex>
first <pointer to graphVertex> nextEdge <pointer to
graphEdge>
end graphHead inTree <boolean>
weight <integer>
end graphEdge
graphVertex
nextVertex <pointer to graphVertex>
data <data type>
inDegree <integer>
outDegree <integer>
inTree <boolean>
pathLength <integer> /* shortest path to the source vertex */
49
edge <pointer to graphEdge>
Shortest Path Algorithm
Algorithm shortestPath (val graph <graphHead>) /* Dijkstra's algorithm */
Determines the shortest path from the first vertex to other vertices
Pre graph is a graph head structure
Post minimum path tree determined
1 if (empty graph)
1 return
2 vertexPtr = graph.first
3 loop (vertexPtr not null)
initialize inTree flags & path length
1 vertexPtr −> inTree = false
2 vertexPtr -> pathLength = +∝
3 edgePtr = vertexPtr −> edge
4 loop (edgePtr not null)
1 edgePtr -> inTree = false
2 edgePtr = edgePtr -> nextEdge
5 vertexPtr = vertexPtr -> nextVertex
50
Now derive minimum path tree 5 5
4 vertexPtr = graph.first B D 3
5 vertexPtr -> inTree = true
6 vertexPtr -> pathLength = 0 A 3 2 F
7 treeComplete = false
8 loop (not treeComplete)
5
C E
1 treeComplete = true 3 4
2 chkVertexPtr = vertexPtr
3 minEdgePtr = null /* to a vertex already in the tree */
4 minPathPtr = null /* to the source vertex */
5 newPathLen = +∝
51
6 loop (chkVertexPtr not null)
Walk thru graph checking vertices in tree
1 if (chkVertexPtr -> inTree = true AND chkVertexPtr -> outDegree >
0)
1 edgePtr = chkVertexPtr -> edge
2 chkPath = chkVertexPtr -> pathLength
3 minEdge = +∝
4 loop (edgePtr not null)
1 if (edgePtr -> destination -> inTree = false)
1 treeComplete = false
2 if (edgePtr -> weight < minEdge)
1 minEdge = edgePtr -> weight
2 minEdgePtr = edgePtr
2 edgePtr = edgePtr -> nextEdge
Test for shortest path
5 if (chkPath + minEdge < newPathLen)
1 newPathLen = minPath + minEdge
2 minPathPtr = minEdgePtr
2 chkVertexPtr = chkVertexPtr -> nextVertex
7 if (pathPtr not null)
Found edge to insert into tree
1 minPathPtr -> inTree = true
2 minPathPtr -> destination -> inTree = true
3 minPathPtr -> destination -> pathLength = newPathLen
9 return
52
End shortestPath
Shortest Path
• What if a negative weight?
5
6 B D 3
-10 3 2 F
A
3 5
C E
4
53
Shortest Path
• What if a negative weight?
5
6 B D 3
-10 3 2 F
A
3 5
C E
4
FAIL!
54
Shortest Path
• What if a directed graph?
5
6 B D 3
A 2 3 2 F
3 5
C E
4
55
Maximum Flows
• A network of water pipelines from one
source to one destination.
56
Maximum Flows
• The flow thru a pipeline cannot be greater
than its capacity.
57
Maximum Flows
• The flow thru a pipeline cannot be greater
than its capacity.
58
Maximum Flows
5
A B
2 3
2 5
4 2
S C 3 2 D T
1 1
3
E F
59
Maximum Flows
5
A B
2 3
2 5
4 2
S C 3 2 D T
1 1
3 3
E F A B
2 3
1 0
2 1
S C 1 1 D T
1 1
0
E F
60
Matching
• Applicants: p q r s t
• Suitable jobs: a b c bd ae e c
de
61
Matching
• Applicants: p q r s t
• Suitable jobs: a b c bd ae e c
de
• Suitable jobs: a b c bd ae e c
de
p q r s t
a b c d e
63
Matching
• Applicants: p q r s t
• Suitable jobs: a b c bd ae e c
de
p q r s t
a b c d e
64
Matching
• Maximum matching: as many pairs of
worker-job as possible.
65
Graph Coloring
• Given a map of adjacent regions.
66
Graph Coloring
67
Graph Coloring
68
Graph Coloring
The problem is to
find the minimum
number of sets of
non-adjacent
vertices.
69
Graph Coloring
The problem is to
find the minimum
number of sets of
non-adjacent
vertices.
70