--- title: Topological Sort description: 'Topological sort or topological ordering of a directed graph is an ordering of nodes such that every node appears in the ordering before all the nodes it points to. ' hidden: true --- ## Directed Graph Before we get started on topological order, let's talk about directed graphs first. A graph is directed when its edges have directions (these edges are also called arcs). Suppose that v, w are vertices in a directed graph. Let's get familiar with a few concepts. - in-edge - an edge pointing to or coming into the node - out-edge - an edge pointing away or going out from the node (we will refer those nodes on the other end of the out-edges of v to v's neighbors) - in-degree - the number of in-edges coming into the node - out-degree - the number of out-edges going out from the node - dependency - "v depends on w" / "v is dependent on w" means that there is a directed path from w to v where v, w are vertices in a directed graph. With these new terms under our belt, it will make more sense when we talk about directed graphs. ## What is a topological order? Topological sort is not unique. For example, for a graph like this: ![Topological sort example](../../public/topo_intro_1.png) Both `[4, 5, 2]` and `[5, 4, 2]` are valid topological orders. ![Topological sort example](../../public/topo_intro_2.png) Task 3 is completely independent of task 2 and 4, and it can be anywhere in the order as long as it is before task 1 which depends on it. All of the following ordering are valid topological orderings. `[4, 2, 3, 1], [4, 3, 2, 1], [3, 4, 2, 1]` :::warning[Graphs with Cycles Do Not Have Topological Ordering] It should be obvious that if a graph with a cycle does not have a topological ordering. In the above example, 2 has to come before 5 which has come before 4 which has to come before 2 which has to come before 5... which is impossible. ::: ## Example Code :::note Notice the topological sort algorithm is very similar to BFS. The main difference is that we only push nodes with 0 in-degree into the queue in topological sort whereas in BFS we push all the neighboring nodes into the queue. ::: ```py from collections import deque def find_indegree(graph): indegree = { node: 0 for node in graph } # dict for node in graph: for neighbor in graph[node]: indegree[neighbor] += 1 return indegree def topo_sort(graph): res = [] q = deque() indegree = find_indegree(graph) for node in indegree: if indegree[node] == 0: q.append(node) while len(q) > 0: node = q.popleft() res.append(node) for neighbor in graph[node]: indegree[neighbor] -= 1 if indegree[neighbor] == 0: q.append(neighbor) return res if len(graph) == len(res) else None ```