coding-interview|November 20, 2020|2 min read

Graph Topological Sorting - Build System Order Example

TL;DR

Topological sort uses DFS with a stack — push a vertex after all its dependents are visited. The reversed stack gives you a valid build order. Only works on DAGs.

Graph Topological Sorting - Build System Order Example

Graph Topological Sorting

This is a well known problem in graph world. Topological sort is to put vertices in order and output a list of vertices in such an order that vertices are in order of dependencies. i.e. The vertices comes first is the independent one, then list the one which are dependent on those.

Connected Graph

In above Directed Graph, following can be possible topological sort order:

A B C D E F G H
OR
A C B E G D F H
OR
B E G A D C F H

Build System Example

The usage of this sort is in the Build system. A build system is where there are different projects or modules are to built. And, it is to decide which module to build first so that updated module can be integrated in the dependent project or module.

Code

class Node {
  //to represent a Vertex
  public String name;
  public List<Node> connectedNodes;
  //...some other data
  public List<Node> adj() {
    return this.connectedNodes;
  }
}
class Graph {
  private List<Node> nodes;
  public List<Node> nodes() {
    return this.nodes;
  }
  
}

public Stack<Node> topological(Graph g) {
  //assumming Graph has method nodes() which gives list of all nodes.
  List<Node> nodes = g.nodes();

  //Set to keep track of visited nodes
  Set<Node> visited = new HashSet();

  //For keeping nodes in order
  Stack<Node> stack = new Stack();

  for (Node node : nodes) {
    helper(node, visited, stack);
  }
}

private void helper(Node node, Set visited, Stack stack) {
    if (visited.contains(node)) {
      continue;
    }
    //mark node visited
    visited.add(node);

    //visit all attached nodes with this vertices
    //Assumming there is a method adj() which gives connected nodes to a vertex
    for (Node n : node.adj()) {
      //recursively visit each node's connected vertices
      helper(n, visited, stack);
    }

    //all connected vertices are exhausted. 
    //Lets add this to our order list
    stack.add(node);
}

//main 
Stack<Node> stack = topological(graph);
//print stack

Complexity

Its O(n)

Related Posts

Binary Tree - Level Order Traversal

Binary Tree - Level Order Traversal

Problem Statement Given a Binary tree, print out nodes in level order traversal…

Move Zeroes - Leet Code Solution

Move Zeroes - Leet Code Solution

Problem Statement Given an array nums, write a function to move all 0’s to the…

Validate Sudoku - Leet Code Solution

Validate Sudoku - Leet Code Solution

Problem Statement Determine if a 9x9 Sudoku board is valid. Only the filled…

Index for Coding Problems

Index for Coding Problems

Sorting Problems Merge Sort Quick Sort Heap Sort Bubble Sort Selection Sort…

Insertion Sort Algorithm

Insertion Sort Algorithm

Its a kind of incremental insertion technique, where the algorithm build up…

Maximum Length of Subarray With Positive Product - Leet Code Solution

Maximum Length of Subarray With Positive Product - Leet Code Solution

Problem Statement Maximum Length of Subarray With Positive Product. Given an…

Latest Posts

System Design Patterns for Managing Long-Running Tasks

System Design Patterns for Managing Long-Running Tasks

Introduction Some operations simply can’t finish in the time a user is willing…

System Design Patterns for Real-Time Updates at High Traffic

System Design Patterns for Real-Time Updates at High Traffic

The previous articles in this series covered scaling reads and scaling writes…

System Design Patterns for Handling Large Blobs

System Design Patterns for Handling Large Blobs

Introduction Every non-trivial application eventually needs to handle large…

Explaining SAGA Patterns with Examples

Explaining SAGA Patterns with Examples

In a monolith, placing an order is a single database transaction — deduct…

System Design Patterns for Scaling Writes

System Design Patterns for Scaling Writes

In the companion article on scaling reads, we covered caching, replicas, and…

Serverless vs Containers — The Decision I Keep Revisiting

Serverless vs Containers — The Decision I Keep Revisiting

Every time I start a new service, I have the same argument with myself. Lambda…