Given a directed graph, check whether the graph contains a cycle or not. Your function should return true if the given graph contains at least one cycle, else return false.
Example,
Input: n = 4, e = 6 0 -> 1, 0 -> 2, 1 -> 2, 2 -> 0, 2 -> 3, 3 -> 3 Output: Yes Explanation: Diagram:The diagram clearly shows a cycle 0 -> 2 -> 0 Input:n = 4, e = 3 0 -> 1, 0 -> 2, 1 -> 2, 2 -> 3 Output:No Explanation: Diagram:
The diagram clearly shows no cycle
Solution using Depth First Search or DFS
- Approach: Depth First Traversal can be used to detect a cycle in a Graph. DFS for a connected graph produces a tree. There is a cycle in a graph only if there is a back edge present in the graph. A back edge is an edge that is from a node to itself (self-loop) or one of its ancestors in the tree produced by DFS. In the following graph, there are 3 back edges, marked with a cross sign. We can observe that these 3 back edges indicate 3 cycles present in the graph.
For a disconnected graph, Get the DFS forest as output. To detect cycle, check for a cycle in individual trees by checking back edges.
To detect a back edge, keep track of vertices currently in the recursion stack of function for DFS traversal. If a vertex is reached that is already in the recursion stack, then there is a cycle in the tree. The edge that connects the current vertex to the vertex in the recursion stack is a back edge. Use recStack[] array to keep track of vertices in the recursion stack.
Dry run of the above approach:

- Algorithm:
- Create the graph using the given number of edges and vertices.
- Create a recursive function that initializes the current index or vertex, visited, and recursion stack.
- Mark the current node as visited and also mark the index in recursion stack.
- Find all the vertices which are not visited and are adjacent to the current node. Recursively call the function for those vertices, If the recursive function returns true, return true.
- If the adjacent vertices are already marked in the recursion stack then return true.
- Create a wrapper class, that calls the recursive function for all the vertices and if any function returns true return true. Else if for all vertices the function returns false return false.
-
Implementation:
C++
// A C++ Program to detect cycle in a graph#include<bits/stdc++.h>usingnamespacestd;classGraph{intV;// No. of verticeslist<int> *adj;// Pointer to an array containing adjacency listsboolisCyclicUtil(intv,boolvisited[],bool*rs);// used by isCyclic()public:Graph(intV);// ConstructorvoidaddEdge(intv,intw);// to add an edge to graphboolisCyclic();// returns true if there is a cycle in this graph};Graph::Graph(intV){this->V = V;adj =newlist<int>[V];}voidGraph::addEdge(intv,intw){adj[v].push_back(w);// Add w to v’s list.}// This function is a variation of DFSUtil() in https://www.geeksforgeeks.org/archives/18212boolGraph::isCyclicUtil(intv,boolvisited[],bool*recStack){if(visited[v] ==false){// Mark the current node as visited and part of recursion stackvisited[v] =true;recStack[v] =true;// Recur for all the vertices adjacent to this vertexlist<int>::iterator i;for(i = adj[v].begin(); i != adj[v].end(); ++i){if( !visited[*i] && isCyclicUtil(*i, visited, recStack) )returntrue;elseif(recStack[*i])returntrue;}}recStack[v] =false;// remove the vertex from recursion stackreturnfalse;}// Returns true if the graph contains a cycle, else false.// This function is a variation of DFS() in https://www.geeksforgeeks.org/archives/18212boolGraph::isCyclic(){// Mark all the vertices as not visited and not part of recursion// stackbool*visited =newbool[V];bool*recStack =newbool[V];for(inti = 0; i < V; i++){visited[i] =false;recStack[i] =false;}// Call the recursive helper function to detect cycle in different// DFS treesfor(inti = 0; i < V; i++)if(isCyclicUtil(i, visited, recStack))returntrue;returnfalse;}intmain(){// Create a graph given in the above diagramGraph 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);if(g.isCyclic())cout <<"Graph contains cycle";elsecout <<"Graph doesn't contain cycle";return0;}chevron_rightfilter_noneJava
// A Java Program to detect cycle in a graphimportjava.util.ArrayList;importjava.util.LinkedList;importjava.util.List;classGraph {privatefinalintV;privatefinalList<List<Integer>> adj;publicGraph(intV){this.V = V;adj =newArrayList<>(V);for(inti =0; i < V; i++)adj.add(newLinkedList<>());}// This function is a variation of DFSUtil() inprivatebooleanisCyclicUtil(inti,boolean[] visited,boolean[] recStack){// Mark the current node as visited and// part of recursion stackif(recStack[i])returntrue;if(visited[i])returnfalse;visited[i] =true;recStack[i] =true;List<Integer> children = adj.get(i);for(Integer c: children)if(isCyclicUtil(c, visited, recStack))returntrue;recStack[i] =false;returnfalse;}privatevoidaddEdge(intsource,intdest) {adj.get(source).add(dest);}// Returns true if the graph contains a// cycle, else false.// This function is a variation of DFS() inprivatebooleanisCyclic(){// Mark all the vertices as not visited and// not part of recursion stackboolean[] visited =newboolean[V];boolean[] recStack =newboolean[V];// Call the recursive helper function to// detect cycle in different DFS treesfor(inti =0; i < V; i++)if(isCyclicUtil(i, visited, recStack))returntrue;returnfalse;}// Driver codepublicstaticvoidmain(String[] args){Graph graph =newGraph(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);if(graph.isCyclic())System.out.println("Graph contains cycle");elseSystem.out.println("Graph doesn't "+"contain cycle");}}// This code is contributed by Sagar Shah.chevron_rightfilter_nonePython
# Python program to detect cycle# in a graphfromcollectionsimportdefaultdictclassGraph():def__init__(self,vertices):self.graph=defaultdict(list)self.V=verticesdefaddEdge(self,u,v):self.graph[u].append(v)defisCyclicUtil(self, v, visited, recStack):# Mark current node as visited and# adds to recursion stackvisited[v]=TruerecStack[v]=True# Recur for all neighbours# if any neighbour is visited and in# recStack then graph is cyclicforneighbourinself.graph[v]:ifvisited[neighbour]==False:ifself.isCyclicUtil(neighbour, visited, recStack)==True:returnTrueelifrecStack[neighbour]==True:returnTrue# The node needs to be poped from# recursion stack before function endsrecStack[v]=FalsereturnFalse# Returns true if graph is cyclic else falsedefisCyclic(self):visited=[False]*self.VrecStack=[False]*self.Vfornodeinrange(self.V):ifvisited[node]==False:ifself.isCyclicUtil(node,visited,recStack)==True:returnTruereturnFalseg=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)ifg.isCyclic()==1:print"Graph has a cycle"else:print"Graph has no cycle"# Thanks to Divyanshu Mehta for contributing this codechevron_rightfilter_noneC#
// A C# Program to detect cycle in a graphusingSystem;usingSystem.Collections.Generic;publicclassGraph {privatereadonlyintV;privatereadonlyList<List<int>> adj;publicGraph(intV){this.V = V;adj =newList<List<int>>(V);for(inti = 0; i < V; i++)adj.Add(newList<int>());}// This function is a variation of DFSUtil() inprivateboolisCyclicUtil(inti,bool[] visited,bool[] recStack){// Mark the current node as visited and// part of recursion stackif(recStack[i])returntrue;if(visited[i])returnfalse;visited[i] =true;recStack[i] =true;List<int> children = adj[i];foreach(intcinchildren)if(isCyclicUtil(c, visited, recStack))returntrue;recStack[i] =false;returnfalse;}privatevoidaddEdge(intsou,intdest) {adj[sou].Add(dest);}// Returns true if the graph contains a// cycle, else false.// This function is a variation of DFS() inprivateboolisCyclic(){// Mark all the vertices as not visited and// not part of recursion stackbool[] visited =newbool[V];bool[] recStack =newbool[V];// Call the recursive helper function to// detect cycle in different DFS treesfor(inti = 0; i < V; i++)if(isCyclicUtil(i, visited, recStack))returntrue;returnfalse;}// Driver codepublicstaticvoidMain(String[] args){Graph graph =newGraph(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);if(graph.isCyclic())Console.WriteLine("Graph contains cycle");elseConsole.WriteLine("Graph doesn't "+"contain cycle");}}// This code contributed by Rajput-Jichevron_rightfilter_none
Output:Graph contains cycle
-
Complexity Analysis:
- Time Complexity: O(V+E).
Time Complexity of this method is same as time complexity of DFS traversal which is O(V+E). - Space Complexity: O(V).
To store the visited and recursion stack O(V) space is needed.
- Time Complexity: O(V+E).
In the below article, another O(V + E) method is discussed :
Detect Cycle in a direct graph using colors
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.
Recommended Posts:
- Detect Cycle in a directed graph using colors
- Detect Cycle in a Directed Graph using BFS
- Detect cycle in Directed Graph using Topological Sort
- Detect cycle in the graph using degrees of nodes of graph
- Print negative weight cycle in a Directed Graph
- Print Nodes which are not part of any cycle in a Directed Graph
- Detect cycle in an undirected graph using BFS
- Detect cycle in an undirected graph
- Detect a negative cycle in a Graph using Shortest Path Faster Algorithm
- Detect a negative cycle in a Graph | (Bellman Ford)
- Disjoint Set (Or Union-Find) | Set 1 (Detect Cycle in an Undirected Graph)
- Convert the undirected graph into directed graph such that there is no path of length greater than 1
- Convert undirected connected graph to strongly connected directed graph
- Detect Cycle in a 2D grid
- Find if there is a path between two vertices in a directed graph
- Shortest Path in Directed Acyclic Graph
- Longest Path in a Directed Acyclic Graph
- Shortest path with exactly k edges in a directed and weighted graph
- Assign directions to edges so that the directed graph remains acyclic
- All Topological Sorts of a Directed Acyclic Graph

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.

The diagram clearly shows a cycle 0 -> 2 -> 0
Input:n = 4, e = 3
0 -> 1, 0 -> 2, 1 -> 2, 2 -> 3
Output:No
Explanation:
Diagram:
The diagram clearly shows no cycle
