Skip to content

Commit d67cecb

Browse files
committed
2 parents 1496a09 + d8d0268 commit d67cecb

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ $ coverage report -m
2828
* [Mergesort](sorts/mergesort.py)
2929
* [Radixsort](sorts/radixsort.py)
3030
* [Heapsort](sorts/heapsort.py)
31+
* [Topological Sort](structures/graph.py)
3132

3233
### Searching Algorithms
3334
* [BinarySearch](searches/binary_search.py)

structures/graph.py

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from collections import defaultdict
2+
13
class GraphNode():
24

35
def __init__(self, val):
@@ -9,10 +11,65 @@ def add_adjacent(self, node):
911

1012
def remove_adjacent(self, node):
1113
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
1223

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+
1435
"""
15-
Check if this node is part of a graph with a universal sink.
36+
self.graph[source].append(destination)
1637

38+
def topological_sort(self):
1739
"""
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+

tests/test_topological_sort.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import unittest
2+
from structures.graph import Graph
3+
4+
class TestGraphTopoSort(unittest.TestCase):
5+
6+
def test_topological_sort(self):
7+
graph = Graph(6)
8+
graph.add_edge(5,2)
9+
graph.add_edge(5,0)
10+
11+
graph.add_edge(4,0)
12+
graph.add_edge(4,1)
13+
14+
graph.add_edge(2,3)
15+
16+
graph.add_edge(3,1)
17+
18+
self.assertEqual([5, 4, 2, 3, 1, 0], graph.topological_sort())
19+
20+
21+

0 commit comments

Comments
 (0)