Interview Camp
Technique: Topological Sort
Level: Hard
Sort a graph in topological order.
Questions to Clarify:
Q. For the output, can I return a Stack which contains the nodes in order?
A. Yes (If interviewer wants a list, simply convert the stack to a list in the code)
Q. Is this a directed graph?
A. Yes. (Point out that Topological sort not possible with undirected graph)
Q. Can we assume that the graph has no cycles?
A. Yes. (We do a section on detecting cycles later)
Solution:
Topological sort is very useful in scheduling problems, or when you need to arrange a
graph in order. A topological sort is an ordering of nodes. We arrange nodes such that
for each node N, all its edges point to a node ahead of N.
You could use topological sort to solve several types of problems. For example, say that
you are given a graph of college classes. Each Node represents a class and each edge conveys
that a class is a prerequisite for another. You can use topological sort to calculate the
minimum number of semesters to complete the classes. Check out the video for more details.
You could also use it to find the longest path in a graph, which we will do in the homework
problems.
Note: Topological Sort is only possible if the Graph has no cycles.
It is also applicable only to directed graphs. In undirected graphs, every edge
can be considered a cycle since it points both ways.
To implement Topological sort, you simply add 1 line to Depth First Search (DFS).
At the end of the dfsVisit() function call, simply add the visited node to a stack.
At the end of the DFS, the stack will contain the nodes in topological order. Try it yourself
with examples.
Pseudocode:
dfsVisit(Node, Stack)
Node.state = VISITING
For each neighbor:
if Neighbor is UNVISITED
perform dfsVisit on Neighbor
Node.state = VISITED
© 2017 Interview Camp (interviewcamp.io)
Interview Camp
Stack.push(Node)
topoSort(Graph)
Stack = empty
for all nodes in Graph:
if node is UNVISITED, perform dfsVisit(node, Stack)
return Stack
Test Cases:
Edge Cases: empty graph, null graph
Base Cases: single node graph, 2 node graph, 2 node unconnected
Regular Cases: multiple nodes, multiple connected components
Time Complexity: O(V + E), where V is vertices (nodes) and E is edges.
Space Complexity: O(V)
public static Stack<Node> topoSort(Graph graph) {
Stack<Node> stack = new Stack<>();
for(Node node : graph.getNodes()) {
if (node.getState() == State.UNVISITED)
dfsVisit(node, stack);
}
return stack;
}
public static void dfsVisit(Node node, Stack<Node> stack) {
node.setState(State.VISITING);
for (Node neighbor: node.getNeighbors()) {
if (neighbor.getState() == State.UNVISITED)
dfsVisit(neighbor, stack);
}
node.setState(State.VISITED);
stack.push(node);
}
/*
* Helper Code. Ask interviewer before implementing.
*/
public enum State {
UNVISITED,
VISITING,
VISITED;
© 2017 Interview Camp (interviewcamp.io)
Interview Camp
public class Graph {
List<Node> nodes;
public Graph(List<Node> nodes) {
super();
this.nodes = nodes;
}
public void addNode(Node node) {
nodes.add(node);
}
public List<Node> getNodes() {
return nodes;
}
}
public class Node {
List<Node> neighbors;
int data;
State state;
public Node(int data) {
super();
this.data = data;
state = State.UNVISITED;
neighbors = new ArrayList<Node>();
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
© 2017 Interview Camp (interviewcamp.io)
Interview Camp
public void addNeighbor(Node node) {
neighbors.add(node);
}
public List<Node> getNeighbors() {
return neighbors;
}
}
© 2017 Interview Camp (interviewcamp.io)