1
+ from collections import defaultdict
2
+
1
3
class GraphNode ():
2
4
3
5
def __init__ (self , val ):
@@ -9,10 +11,65 @@ def add_adjacent(self, node):
9
11
10
12
def remove_adjacent (self , node ):
11
13
self .adjacent_list .remove (node )
14
+
15
+ class Graph ():
16
+ """
17
+ A directed graph represented with an adjacency list.
18
+ """
19
+
20
+ def __init__ (self , verticies ):
21
+ self .graph = defaultdict (list )
22
+ self .verticies = verticies
12
23
13
- def contains_universal_sink (self ):
24
+ def add_edge (self , source , destination ):
25
+ """
26
+ Add an edge to the graph.
27
+
28
+ Add an edge pointing from source vertex
29
+ to destination vertex.
30
+
31
+ Args:
32
+ source: the source vertex
33
+ destination: the destination vertex
34
+
14
35
"""
15
- Check if this node is part of a graph with a universal sink.
36
+ self . graph [ source ]. append ( destination )
16
37
38
+ def topological_sort (self ):
17
39
"""
18
-
40
+ Sort the graph topologically.
41
+
42
+ A topological sort lists nodes in such a way
43
+ that every node 's' in 's' -> 'd' directed pairs
44
+ is listed before 'd.' This will not work in a
45
+ graph that contains cycles.
46
+
47
+ The algorithm looks at every node, and does a
48
+ dfs for each node adjacent to the node and then adds
49
+ the originating node to a stack once all adjacent
50
+ nodes have been searched. In the end, the stack
51
+ will be in order of a possible topological sort.
52
+
53
+ Topological sorts are not necessarily unique.
54
+
55
+ Returns:
56
+ A list of vertices in a topological ordering.
57
+
58
+ """
59
+ visited = set ()
60
+ stack = []
61
+
62
+ def dfs (vertex ):
63
+ visited .add (vertex )
64
+ for i in self .graph [vertex ]:
65
+ if i not in visited :
66
+ dfs (i )
67
+
68
+ stack .insert (0 , vertex )
69
+
70
+ for i in range (self .verticies ):
71
+ if i not in visited :
72
+ dfs (i )
73
+
74
+ return stack
75
+
0 commit comments