1. Mark the source_node as visited. 2. Mark the source_node as in_path node. 3. For all the adjacent nodes to the source_node do 4. If the adjacent node has been marked as in_path node, then 5. Cycle found. Return. 6. If the adjacent node has not been visited, then 7. Detect_Cycle ( adjacent_node ) 8. Now that we are backtracking unmark the source_node in in_path as it might be revisited.
Example
Time complexity : O ( E + V ). This algorithm uses a depth-first search traversal for traversing all the nodes in the graph. As the graph is stored in an adjacency list, the neighbors of a vertex on the outgoing edge are explored successively/linearly. As each vertex is explored only once, all the vertices are explored in O ( V ) time. The total number of edges (maintained in the adjacency list) are E for a directed graph. Thus the time complexity is O ( E + V ) for a directed graph.
Program for detecting cycle in a directed graph
Python C++ Javafrom collections import defaultdict class Graph: def __init__(self, nodes : int): # The default dictionary would create an empty list as a default (value) # for the nonexistent keys. self.adjlist = defaultdict(list) self.nodes = nodes self.visited = [False] * nodes # inpath stores the visited nodes in the traversal path # for finding cycle in a directed graph. self.inpath = [False] * nodes self.cycle_present = False def AddEdge (self, src : int, dst : int, bidirectional : bool): self.adjlist[src].append(dst) if bidirectional: # Check if the edge is undirected (bidirectional) self.adjlist[dst].append(src) # Function detects cycle in a directed graph using # DFS technique at its core. def DetectCycle (self, src : int): self.visited[src] = True # Set the flag for the vertex visited in traversal path self.inpath[src] = True for adj_node in self.adjlist[src]: if self.inpath[adj_node] == True: self.cycle_present = True return elif self.visited[adj_node] == False: self.DetectCycle (adj_node) # Before we backtrack unset the flag for the src vertex as it # might be in the next traversal path self.inpath[src] = False # Mark nodes unvisited for the next traversal def MarkUnvisited (self): self.visited = [False] * nodes def CyclePresent (self): return self.cycle_present def main(): nodes = 7 g1_directed = Graph(nodes) # Graph 1 # 6----------- # ^ | # | | # 4 # ^ ^ # | | # 1 # ^ ^ # | | # 0 ----->2 # Add edges to the directed graph g1_directed.AddEdge(0, 1, False) g1_directed.AddEdge(0, 2, False) g1_directed.AddEdge(1, 4, False) g1_directed.AddEdge(2, 3, False) g1_directed.AddEdge(3, 1, False) g1_directed.AddEdge(3, 5, False) g1_directed.AddEdge(4, 6, False) g1_directed.AddEdge(5, 4, False) g1_directed.AddEdge(6, 5, False) g1_directed.DetectCycle(0) if g1_directed.CyclePresent() == True: print("Cycle found in the directed graph g1") else: print("Cycle not found in the directed graph g1") # Graph 2 # 4- # ^ \ # | \ # 3 \ # ^ \ # | \ # 2 \ # ^ \ # | \ # 0--->1 nodes = 5 g2_directed = Graph(nodes) g2_directed.AddEdge(0, 1, False) g2_directed.AddEdge(0, 2, False) g2_directed.AddEdge(2, 3, False) g2_directed.AddEdge(3, 4, False) g2_directed.AddEdge(4, 1, False) g2_directed.DetectCycle(0) if g2_directed.CyclePresent() == True: print("Cycle found in the directed graph g2") else: print("Cycle not found in the directed graph g2") if __name__ == "__main__": main()
Cycle found in the directed graph g1 Cycle not found in the directed graph g2
#include #include #include #include using namespace std; class Graph private: int nodes; listint> *adjlist; vectorbool> visited; // inpath stores the visited nodes in the traversal path before backtracking // for finding cycle in a directed graph. vectorbool> inpath; bool cycle_present; public: Graph() > Graph (int arg_nodes) this->nodes = arg_nodes; adjlist = new listint> [nodes]; visited.resize(nodes, false); inpath.resize(nodes, false); cycle_present = false; > ~Graph () delete [] adjlist; > void AddEdge (int src, int dst, bool bidirectional) adjlist[src].push_back(dst); if (bidirectional) adjlist[dst].push_back(src); > // Function detects cycle in a directed graph // using DFS technique at its core void DetectCycle (int src) visited[src] = true; // Set the flag for the vertex visited in traversal path // inpath[src] = true; for (auto& adj_node : adjlist[src]) if (inpath[adj_node]) cycle_present = true; return; > else if (!visited[adj_node]) DetectCycle (adj_node); > > // Before we backtrack unset the flag for the src vertex as it will // not be in the next traversal path inpath[src] = false; > // Mark nodes unvisited for the next traversal void MarkUnvisited () fill(visited.begin(), visited.end(), false); > bool CyclePresent() return cycle_present; > >; int main() Graph g1_directed (7); /* Graph 1 6----------- ^ | | | 4 ^ ^ | | 1 ^ ^ | | 0 ----->2 */ // Add edges to the directed graph g1_directed.AddEdge(0, 1, false); g1_directed.AddEdge(0, 2, false); g1_directed.AddEdge(1, 4, false); g1_directed.AddEdge(2, 3, false); g1_directed.AddEdge(3, 1, false); g1_directed.AddEdge(3, 5, false); g1_directed.AddEdge(4, 6, false); g1_directed.AddEdge(5, 4, false); g1_directed.AddEdge(6, 5, false); g1_directed.DetectCycle(0); if (g1_directed.CyclePresent()) cout <"Cycle found in the directed graph g1" > else cout <"Cycle not found in the directed graph g1" > Graph g2_directed (5); /* Graph 2 4- ^ \ | \ 3 \ ^ \ | \ 2 \ ^ \ | \ 0--->1 */ g2_directed.AddEdge(0, 1, false); g2_directed.AddEdge(0, 2, false); g2_directed.AddEdge(2, 3, false); g2_directed.AddEdge(3, 4, false); g2_directed.AddEdge(4, 1, false); g2_directed.DetectCycle(0); if (g2_directed.CyclePresent()) cout <"Cycle found in the directed graph g2" > else cout <"Cycle not found in the directed graph g2" > return 0; >
Cycle found in the directed graph g1 Cycle not found in the directed graph g2
import java.util.Arrays; import java.util.ArrayList; import java.util.List; class Graph private int nodes; private ListListInteger>> adjlist; private boolean visited[]; // inpath stores the visited nodes in the traversal path before backtracking // for finding cycle in a directed graph. private boolean inpath[]; boolean cycle_present; Graph (int arg_nodes) nodes = arg_nodes; adjlist = new ArrayList<> (nodes); for(int i=0; inodes; i++) adjlist.add(new ArrayList<>()); > visited = new boolean[nodes]; inpath = new boolean[nodes]; cycle_present = false; > public void AddEdge (int src, int dst, boolean bidirectional) adjlist.get(src).add(dst); if (bidirectional) adjlist.get(dst).add(src); > // Function detects cycle in a directed graph // using DFS technique at its core. public void DetectCycle (int src) visited[src] = true; // Set the flag for the vertex visited in traversal path // inpath[src] = true; for (int adj_node : adjlist.get(src)) if (inpath[adj_node]) cycle_present = true; return; > else if (!visited[adj_node]) DetectCycle (adj_node); > > // Before we backtrack unset the flag for the src vertex as it will // not be in the next traversal path inpath[src] = false; > // Mark nodes unvisited for the next traversal public void MarkUnvisited () Arrays.fill(visited, false); > public boolean CyclePresent() return cycle_present; > public static void main (String[] args) Graph g1_directed = new Graph(7); /* Graph 1 6----------- ^ | | | 4 ^ ^ | | 1 ^ ^ | | 0 ----->2 */ // Add edges to the directed graph g1_directed.AddEdge(0, 1, false); g1_directed.AddEdge(0, 2, false); g1_directed.AddEdge(1, 4, false); g1_directed.AddEdge(2, 3, false); g1_directed.AddEdge(3, 1, false); g1_directed.AddEdge(3, 5, false); g1_directed.AddEdge(4, 6, false); g1_directed.AddEdge(5, 4, false); g1_directed.AddEdge(6, 5, false); g1_directed.DetectCycle(0); if (g1_directed.CyclePresent()) System.out.println("Cycle found in the directed graph g1"); > else System.out.println("Cycle not found in the directed graph g1"); > Graph g2_directed = new Graph(5); /* Graph 2 4- ^ \ | \ 3 \ ^ \ | \ 2 \ ^ \ | \ 0--->1 */ g2_directed.AddEdge(0, 1, false); g2_directed.AddEdge(0, 2, false); g2_directed.AddEdge(2, 3, false); g2_directed.AddEdge(3, 4, false); g2_directed.AddEdge(4, 1, false); g2_directed.DetectCycle(0); if (g2_directed.CyclePresent()) System.out.println("Cycle found in the directed graph g2"); > else System.out.println("Cycle not found in the directed graph g2"); > > >
Cycle found in the directed graph g1 Cycle not found in the directed graph g2
Copyright (c) 2019-2024, Algotree.org. All rights reserved.