Open in App
Not now

# Detect Cycle in a Directed Graph

• Difficulty Level : Medium
• Last Updated : 22 Mar, 2023

Given the root of a Directed graph, The task is to check whether the graph contains a cycle or not.

Examples:

Input: N = 4, E = 6

Example of graph

Output: Yes
Explanation: The diagram clearly shows a cycle 0 -> 2 -> 0

Input: N = 4, E = 4

Output: No
Explanation: The diagram clearly shows no cycle

Approach:

The problem can be solved based on the following idea:

To find cycle in a directed graph we can use the Depth First Traversal (DFS) technique. It is based on the idea that there is a cycle in a graph only if there is a back edge [i.e., a node points to one of its ancestors] present in the graph.

To detect a back edge, we need to keep track of the nodes visited till now and the nodes that are in the current recursion stack [i.e., the current path that we are visiting]. If during recursion, we reach a node that is already in the recursion stack, there is a cycle present in the graph.

Note: If the graph is disconnected then get the DFS forest and check for a cycle in individual trees by checking back edges.

Follow the below steps to Implement the idea:

• Create a recursive dfs function that has the following parameters – current vertex, visited array, and recursion stack.
• Mark the current node as visited and also mark the index in the recursion stack.
• Iterate a loop for all the vertices and for each vertex, call the recursive function if it is not yet visited (This step is done to make sure that if there is a forest of graphs, we are checking each forest):
• In each recursion call, Find all the adjacent vertices of the current vertex which are not visited:
• If an adjacent vertex is already marked in the recursion stack then return true.
• Otherwise, call the recursive function for that adjacent vertex.
• While returning from the recursion call, unmark the current node from the recursion stack, to represent that the current node is no longer a part of the path being traced.
• If any of the functions returns true, stop the future function calls and return true as the answer.

Illustration:

Consider the following graph:

Example of a Directed Graph

Consider we start the iteration from vertex 0.

• Initially, 0 will be marked in both the visited[] and recStack[] array as it is a part of the current path.

Vertex 0 is visited

• Now 0 has two adjacent vertices 1 and 2. Let us consider traversal to the vertex 1. So 1 will be marked in both visited[] and recStack[].

Vertex 1 is visited

• Vertex 1 has only one adjacent vertex. Call the recursive function for 2 and mark it in visited[] and recStack[].

Vertex 2 is visited

• Vertex 2 also has two adjacent vertices.
• Vertex 0 is visited and already marked in the recStack[]. So if 0 is checked first, we will get the answer that there is a cycle present.
• On the other hand, if vertex 3 is checked first, then 3 will be marked in visited[] and recStack[].

Vertex 3 is visited

• While returning from the recursion call for 3, it will be unmarked from recStack[] as it is now not a part of the path currently being traced.

Vertex 3 is unmarked from recStack[]

• Now we have only one option to check, vertex 0, which is already marked in recStack[].

So, we can conclude that a cycle exists. We can also find the cycle if we have traversed to vertex 2 from 0 itself in this same way.

Below is the implementation of the above approach:

## C++

 `// A C++ Program to detect cycle in a graph` `#include ` `using` `namespace` `std;`   `class` `Graph {` `    ``// No. of vertices` `    ``int` `V;`   `    ``// Pointer to an array containing adjacency lists` `    ``list<``int``>* adj;`   `    ``// Used by isCyclic()` `    ``bool` `isCyclicUtil(``int` `v, ``bool` `visited[], ``bool``* rs);`   `public``:` `    ``Graph(``int` `V);` `    ``void` `addEdge(``int` `v, ``int` `w);` `    ``bool` `isCyclic();` `};`   `Graph::Graph(``int` `V)` `{` `    ``this``->V = V;` `    ``adj = ``new` `list<``int``>[V];` `}`   `void` `Graph::addEdge(``int` `v, ``int` `w)` `{` `    ``// Add w to vâ€™s list.` `    ``adj[v].push_back(w);` `}`   `// DFS function to find if a cycle exists` `bool` `Graph::isCyclicUtil(``int` `v, ``bool` `visited[],` `                         ``bool``* recStack)` `{` `    ``if` `(visited[v] == ``false``) {` `        ``// Mark the current node as visited` `        ``// and part of recursion stack` `        ``visited[v] = ``true``;` `        ``recStack[v] = ``true``;`   `        ``// Recur for all the vertices adjacent to this` `        ``// vertex` `        ``list<``int``>::iterator i;` `        ``for` `(i = adj[v].begin(); i != adj[v].end(); ++i) {` `            ``if` `(!visited[*i]` `                ``&& isCyclicUtil(*i, visited, recStack))` `                ``return` `true``;` `            ``else` `if` `(recStack[*i])` `                ``return` `true``;` `        ``}` `    ``}`   `    ``// Remove the vertex from recursion stack` `    ``recStack[v] = ``false``;` `    ``return` `false``;` `}`   `// Returns true if the graph contains a cycle, else false` `bool` `Graph::isCyclic()` `{` `    ``// Mark all the vertices as not visited` `    ``// and not part of recursion stack` `    ``bool``* visited = ``new` `bool``[V];` `    ``bool``* recStack = ``new` `bool``[V];` `    ``for` `(``int` `i = 0; i < V; i++) {` `        ``visited[i] = ``false``;` `        ``recStack[i] = ``false``;` `    ``}`   `    ``// Call the recursive helper function` `    ``// to detect cycle in different DFS trees` `    ``for` `(``int` `i = 0; i < V; i++)` `        ``if` `(!visited[i]` `            ``&& isCyclicUtil(i, visited, recStack))` `            ``return` `true``;`   `    ``return` `false``;` `}`   `// Driver code` `int` `main()` `{` `    ``// Create a graph` `    ``Graph g(4);` `    ``g.addEdge(0, 1);` `    ``g.addEdge(0, 2);` `    ``g.addEdge(1, 2);` `    ``g.addEdge(2, 0);` `    ``g.addEdge(2, 3);` `    ``g.addEdge(3, 3);`   `    ``// Function call` `    ``if` `(g.isCyclic())` `        ``cout << ``"Graph contains cycle"``;` `    ``else` `        ``cout << ``"Graph doesn't contain cycle"``;` `    ``return` `0;` `}`

## Java

 `// A Java Program to detect cycle in a graph` `import` `java.util.ArrayList;` `import` `java.util.LinkedList;` `import` `java.util.List;`   `class` `Graph {` `    `  `    ``private` `final` `int` `V;` `    ``private` `final` `List> adj;`   `    ``public` `Graph(``int` `V) ` `    ``{` `        ``this``.V = V;` `        ``adj = ``new` `ArrayList<>(V);` `        `  `        ``for` `(``int` `i = ``0``; i < V; i++)` `            ``adj.add(``new` `LinkedList<>());` `    ``}` `    `  `    ``// Function to check if cycle exists` `    ``private` `boolean` `isCyclicUtil(``int` `i, ``boolean``[] visited,` `                                      ``boolean``[] recStack) ` `    ``{` `        `  `        ``// Mark the current node as visited and` `        ``// part of recursion stack` `        ``if` `(recStack[i])` `            ``return` `true``;`   `        ``if` `(visited[i])` `            ``return` `false``;` `            `  `        ``visited[i] = ``true``;`   `        ``recStack[i] = ``true``;` `        ``List children = adj.get(i);` `        `  `        ``for` `(Integer c: children)` `            ``if` `(isCyclicUtil(c, visited, recStack))` `                ``return` `true``;` `                `  `        ``recStack[i] = ``false``;`   `        ``return` `false``;` `    ``}`   `    ``private` `void` `addEdge(``int` `source, ``int` `dest) {` `        ``adj.get(source).add(dest);` `    ``}`   `    ``// Returns true if the graph contains a ` `    ``// cycle, else false.` `    ``private` `boolean` `isCyclic() ` `    ``{       ` `        ``// Mark all the vertices as not visited and` `        ``// not part of recursion stack` `        ``boolean``[] visited = ``new` `boolean``[V];` `        ``boolean``[] recStack = ``new` `boolean``[V];` `             `  `        ``// Call the recursive helper function to` `        ``// detect cycle in different DFS trees` `        ``for` `(``int` `i = ``0``; i < V; i++)` `            ``if` `(isCyclicUtil(i, visited, recStack))` `                ``return` `true``;`   `        ``return` `false``;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``Graph graph = ``new` `Graph(``4``);` `        ``graph.addEdge(``0``, ``1``);` `        ``graph.addEdge(``0``, ``2``);` `        ``graph.addEdge(``1``, ``2``);` `        ``graph.addEdge(``2``, ``0``);` `        ``graph.addEdge(``2``, ``3``);` `        ``graph.addEdge(``3``, ``3``);` `        `  `        ``// Function call` `        ``if``(graph.isCyclic())` `            ``System.out.println(``"Graph contains cycle"``);` `        ``else` `            ``System.out.println(``"Graph doesn't "` `                                    ``+ ``"contain cycle"``);` `    ``}` `}`   `// This code is contributed by Sagar Shah.`

## Python3

 `# Python program to detect cycle` `# in a graph`   `from` `collections ``import` `defaultdict`     `class` `Graph():` `    ``def` `__init__(``self``, vertices):` `        ``self``.graph ``=` `defaultdict(``list``)` `        ``self``.V ``=` `vertices`   `    ``def` `addEdge(``self``, u, v):` `        ``self``.graph[u].append(v)`   `    ``def` `isCyclicUtil(``self``, v, visited, recStack):`   `        ``# Mark current node as visited and` `        ``# adds to recursion stack` `        ``visited[v] ``=` `True` `        ``recStack[v] ``=` `True`   `        ``# Recur for all neighbours` `        ``# if any neighbour is visited and in` `        ``# recStack then graph is cyclic` `        ``for` `neighbour ``in` `self``.graph[v]:` `            ``if` `visited[neighbour] ``=``=` `False``:` `                ``if` `self``.isCyclicUtil(neighbour, visited, recStack) ``=``=` `True``:` `                    ``return` `True` `            ``elif` `recStack[neighbour] ``=``=` `True``:` `                ``return` `True`   `        ``# The node needs to be popped from` `        ``# recursion stack before function ends` `        ``recStack[v] ``=` `False` `        ``return` `False`   `    ``# Returns true if graph is cyclic else false` `    ``def` `isCyclic(``self``):` `        ``visited ``=` `[``False``] ``*` `(``self``.V ``+` `1``)` `        ``recStack ``=` `[``False``] ``*` `(``self``.V ``+` `1``)` `        ``for` `node ``in` `range``(``self``.V):` `            ``if` `visited[node] ``=``=` `False``:` `                ``if` `self``.isCyclicUtil(node, visited, recStack) ``=``=` `True``:` `                    ``return` `True` `        ``return` `False`     `# Driver code` `if` `__name__ ``=``=` `'__main__'``:` `    ``g ``=` `Graph(``4``)` `    ``g.addEdge(``0``, ``1``)` `    ``g.addEdge(``0``, ``2``)` `    ``g.addEdge(``1``, ``2``)` `    ``g.addEdge(``2``, ``0``)` `    ``g.addEdge(``2``, ``3``)` `    ``g.addEdge(``3``, ``3``)`   `    ``if` `g.isCyclic() ``=``=` `1``:` `        ``print``(``"Graph contains cycle"``)` `    ``else``:` `        ``print``(``"Graph doesn't contain cycle"``)`   `# Thanks to Divyanshu Mehta for contributing this code`

## C#

 `// A C# Program to detect cycle in a graph` `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `Graph {`   `    ``private` `readonly` `int` `V;` `    ``private` `readonly` `List > adj;`   `    ``public` `Graph(``int` `V)` `    ``{` `        ``this``.V = V;` `        ``adj = ``new` `List >(V);`   `        ``for` `(``int` `i = 0; i < V; i++)` `            ``adj.Add(``new` `List<``int``>());` `    ``}`   `    ``// Function to check if cycle exists` `    ``private` `bool` `isCyclicUtil(``int` `i, ``bool``[] visited,` `                              ``bool``[] recStack)` `    ``{` `        ``// Mark the current node as visited and` `        ``// part of recursion stack` `        ``if` `(recStack[i])` `            ``return` `true``;`   `        ``if` `(visited[i])` `            ``return` `false``;`   `        ``visited[i] = ``true``;`   `        ``recStack[i] = ``true``;` `        ``List<``int``> children = adj[i];`   `        ``foreach``(``int` `c ``in` `children) ``if` `(` `            ``isCyclicUtil(c, visited, recStack)) ``return` `true``;`   `        ``recStack[i] = ``false``;`   `        ``return` `false``;` `    ``}`   `    ``private` `void` `addEdge(``int` `sou, ``int` `dest)` `    ``{` `        ``adj[sou].Add(dest);` `    ``}`   `    ``// Returns true if the graph contains a` `    ``// cycle, else false` `    ``private` `bool` `isCyclic()` `    ``{` `        ``// Mark all the vertices as not visited and` `        ``// not part of recursion stack` `        ``bool``[] visited = ``new` `bool``[V];` `        ``bool``[] recStack = ``new` `bool``[V];`   `        ``// Call the recursive helper function to` `        ``// detect cycle in different DFS trees` `        ``for` `(``int` `i = 0; i < V; i++)` `            ``if` `(isCyclicUtil(i, visited, recStack))` `                ``return` `true``;`   `        ``return` `false``;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `Main(String[] args)` `    ``{` `        ``Graph graph = ``new` `Graph(4);` `        ``graph.addEdge(0, 1);` `        ``graph.addEdge(0, 2);` `        ``graph.addEdge(1, 2);` `        ``graph.addEdge(2, 0);` `        ``graph.addEdge(2, 3);` `        ``graph.addEdge(3, 3);`   `        ``// Function call` `        ``if` `(graph.isCyclic())` `            ``Console.WriteLine(``"Graph contains cycle"``);` `        ``else` `            ``Console.WriteLine(``"Graph doesn't "` `                              ``+ ``"contain cycle"``);` `    ``}` `}`   `// This code contributed by Rajput-Ji`

## Javascript

 `// A JavaScript Program to detect cycle in a graph`   `let V;` `let adj=[];` `function` `Graph(v)` `{` `    ``V=v;` `    ``for` `(let i = 0; i < V; i++)` `        ``adj.push([]);` `}`   `// Function to check if cycle exists` `function` `isCyclicUtil(i,visited,recStack)` `{` `    ``// Mark the current node as visited and` `    ``// part of recursion stack` `        ``if` `(recStack[i])` `            ``return` `true``;` ` `  `        ``if` `(visited[i])` `            ``return` `false``;` `             `  `        ``visited[i] = ``true``;` ` `  `        ``recStack[i] = ``true``;` `        ``let children = adj[i];` `         `  `        ``for` `(let c=0;c< children.length;c++)` `            ``if` `(isCyclicUtil(children, visited, recStack))` `                ``return` `true``;` `                 `  `        ``recStack[i] = ``false``;` ` `  `        ``return` `false``;` `}`   `function` `addEdge(source,dest)` `{` `    ``adj .push(dest);` `}`   `// Returns true if the graph contains a` `// cycle, else false.` `function` `isCyclic()` `{` `    ``// Mark all the vertices as not visited and` `        ``// not part of recursion stack` `        ``let visited = ``new` `Array(V);` `        ``let recStack = ``new` `Array(V);` `        ``for``(let i=0;i

Output

`Graph contains cycle`

Time Complexity: O(V + E), the Time Complexity of this method is the same as the time complexity of DFS traversal which is O(V+E).
Auxiliary Space: O(V). To store the visited and recursion stack O(V) space is needed.

In the below article, another O(V + E) method is discussed :
Detect Cycle in a direct graph using colors

My Personal Notes arrow_drop_up
Related Articles