Lecture 15:
Data Structures (Graphs)
Sookyung Kim
Graphs
2
Definitions
A
B
D
C
E
A
D
C
3
Graph Examples
4
Graph Examples
5
Graph Examples
6
Definitions
A
B
D
C
E
A
B
D
C
E
Simple path
Simple cycle
7
Definitions
Connected graph
Disconnected graph
Complete graph
8
Definitions
Weighted graph
Directed graph
9
Definitions
Multigraph
Self edge
10
Tree vs. Graph?
A
B
D
C
E
A
B
D
C
E
Any node can be the root.
11
Exercise
Graph
Connected
Cyclic
Directed
12
Graph Representation
13
Adjacency Matrix
14
Adjacency Matrix: Example
Directed graph
15
Adjacency Matrix: Example
Weighted undirected graph
16
Adjacency List
17
Adjacency List: Example
Directed graph
18
Adjacency List: Example
Weighted undirected graph
19
Adjacency List: Implementation
class undirected_graph():
def __init__(self, nodes, edges):
self.v = nodes[:]
self.e = {}
for node in nodes:
self.e[node] = []
for (u, v) in edges:
self.e[v].append(u)
self.e[u].append(v)
v = ['a', 'b', 'c']
e = [('a', 'b'), ('b', 'c')]
graph = undirected_graph(v, e)
print(graph.e)
{'a': ['b'], 'b': ['a', 'c'], 'c': ['b']}
20
Google Interview Question
21
Graph Traversal
22
Graph Traversal
j
k
23
Depth First Search (DFS)
j
k
This slide is best seen with animations.
24
Depth First Search (DFS)
a
b
a b
c
a b c
Node visited
Stack (bottom to top)
d
a b c d
g
a b c d g
e
a b c d g e
(backtrack)
a b c d g
f
a b c d g f
(backtrack)
a b c d g
(backtrack)
a b c d
a
h
a b c d h
(backtrack)
a b c d
(backtrack)
a b c
(backtrack)
a b
(backtrack)
a
i
a i
(backtrack)
a
(backtrack)
(empty)
25
Depth First Search (DFS)
def dfs(self):
unvisited = self.v.copy()
stack = Stack()
while not unvisited.is_empty():
visit(unvisited[0]) # visit origin
stack.push(unvisited[0])
del unvisited[0]
while not stack.is_empty():
curr = stack.peek()
if there remains an unvisited city from curr:
next = select an unvisited city from curr
visit(next)
stack.push(next)
delete next from unvisited
else:
stack.pop() # backtracking
Do something when we visit the node.
(e.g., print, compare, …)
For each connected node from curr node (accessed by internal adjacency matrix or list), check if it is in the unvisited.
We need this loop to take care of disconnected nodes!
06 Graph & Search (BFS, DFS)
Time Complexity of DFS
O(1)
O(|V|)
O(1)
O(1)
With adj. matrix
O(|V|)
O(|V|2)
With adj. list
Total number of search�= number of edges (|E|)
O(|V| |E|)
27
Depth First Search (DFS)
28
Depth First Search (DFS)
j
k
Node visited
Stack (bottom to top)
29
Breadth First Search (BFS)
This slide is best seen with animations.
j
k
1
2
3
4
5
6
7
8
1
30
Breadth First Search (BFS)
a
a
b f i
b
f i c e
Node visited
Queue (front to back)
f
i c e g
i
c e g
c
e g d
e
g d
g
d
d
h
h
(empty)
31
Breadth First Search (BFS)
def bfs(self):
unvisited = self.v.copy()
queue = Queue()
while not unvisited.is_empty():
queue.enqueue(some unvisited node)
while not queue.is_empty():
curr = queue.dequeue()
visit(curr)
delete curr from unvisited�
for city in all unvisited cities connected from curr:
queue.enqueue(city)
Do something when we visit the node.
(e.g., print, compare, …)
For each connected node from curr node (accessed by internal adjacency matrix or list), check if it is in the unvisited.
We need this loop to take care of disconnected nodes!
06 Graph & Search (BFS, DFS)
Breadth First Search (BFS)
33
Breadth First Search (BFS)
j
k
Node visited
Queue (front to back)
34
DFS vs. BFS
DFS
BFS
origin
35
Time Complexity of BFS
O(1)
O(|V|)
With adj. matrix
O(|V|)
O(|V|2)
With adj. list
Total number of search�= number of edges (|E|)
O(|V| |E|)
36
Homework
37
HW1: Implement DFS
38
HW2: Implement BFS
39
HW3: Number of islands
40
HW4: Word Ladder
41
HW5: Maximum length of Tree
42