Java Program to Detect Cycle in a Directed Graph
Last Updated :
29 Jul, 2024
Given a directed graph, check whether the graph contains a cycle. Your function should return true if the given graph contains at least one cycle; otherwise, it should return false.
Example:
Input: N = 4, E = 6
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.
Approaches For Cycle Detection
There are two approaches to detect cycles in a directed graph:
- Depth-First Search (DFS)
- Kahn's Algorithm (Topological Sorting)
1. Java Program to Detect Cycle in a Directed Graph using (DFS)
The DFS approach is a popular method for cycle detection in directed graphs. The key idea is to use a recursive function to traverse the graph and maintain two arrays: one for visited nodes and another for nodes currently in the recursion stack (or "visiting" set). If we encounter a node that is already in the recursion stack, a cycle is detected.
- visited[]: To track whether a node has been visited.
- recStack[]: To keep track of nodes currently in the recursion stack.
Graph Class: Representing the Directed Graph
Algorithm to Create a Graph
- Initialize the Graph
- Input: Number of vertices,
V
. - Output: An empty graph with
V
vertices. - Steps:
- Create an adjacency list with
V
empty lists. - Initialize each list to represent the neighbors of each vertex.
- Add an Edge
- Input: Source vertex
src
and destination vertex dest
. - Output: Updated adjacency list with the edge added.
- Steps:
- Append the destination vertex
dest
to the adjacency list of the source vertex src
.
CycleDetection Class: Detecting Cycles
Algorithm to Detect Cycles using DFS
- Depth-First Search (DFS)
- Input: Current vertex
v
, arrays visited
and recStack
, graph object graph
. - Output:
True
if a cycle is detected, otherwise False
. - Steps:
- If
recStack[v]
is True
, return True
(cycle detected). - If
visited[v]
is True
, return False
(no cycle through this vertex). - Mark
v
as visited (visited[v] = True
). - Add
v
to the recursion stack (recStack[v] = True
). - For each neighbor
n
of vertex v
:- Recursively call
dfs(n, visited, recStack, graph)
. - If the recursive call returns
True
, return True
(cycle detected).
- Remove
v
from the recursion stack (recStack[v] = False
). - Return
False
(no cycle detected through this path).
- Cycle Detection
- Input: Graph object
graph
. - Output:
True
if the graph contains a cycle, otherwise False
. - Steps:
- Initialize arrays
visited
and recStack
to False
for all vertices. - For each vertex
v
in the graph:- If
visited[v]
is False
, call dfs(v, visited, recStack, graph)
. - If
dfs
returns True
, return True
(cycle detected).
- Return
False
(no cycle detected)
Implementation cycle detection using DFS in Java:
Java
import java.util.ArrayList;
import java.util.List;
// Graph class representing a directed
// graph using adjacency list
class Graph {
private final int vertices;
private final List<List<Integer>> adjList;
public Graph(int vertices) {
this.vertices = vertices;
adjList = new ArrayList<>(vertices);
for (int i = 0; i < vertices; i++) {
adjList.add(new ArrayList<>());
}
}
public void addEdge(int src, int dest) {
adjList.get(src).add(dest);
}
public List<Integer> getNeighbors(int vertex) {
return adjList.get(vertex);
}
public int getVertices() {
return vertices;
}
}
// CycleDetection class to detect cycles in the graph
class CycleDetection {
private boolean dfs(int vertex, boolean[] visited, boolean[] recStack, Graph graph) {
if (recStack[vertex]) {
return true;
}
if (visited[vertex]) {
return false;
}
visited[vertex] = true;
recStack[vertex] = true;
for (int neighbor : graph.getNeighbors(vertex)) {
if (dfs(neighbor, visited, recStack, graph)) {
return true;
}
}
recStack[vertex] = false;
return false;
}
public boolean hasCycle(Graph graph) {
int vertices = graph.getVertices();
boolean[] visited = new boolean[vertices];
boolean[] recStack = new boolean[vertices];
for (int i = 0; i < vertices; i++) {
if (!visited[i] && dfs(i, visited, recStack, graph)) {
return true;
}
}
return false;
}
}
// Main class to demonstrate the cycle detection
public class Main {
public static void main(String[] args) {
Graph graph = new Graph(4);
graph.addEdge(0, 1);
graph.addEdge(1, 2);
graph.addEdge(2, 0);
graph.addEdge(2, 3);
CycleDetection cycleDetection = new CycleDetection();
boolean hasCycle = cycleDetection.hasCycle(graph);
if (hasCycle) {
System.out.println("The graph contains a cycle.");
} else {
System.out.println("The graph does not contain a cycle.");
}
}
}
OutputThe graph contains a 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.
2. Java Program to Detect Cycle in a Directed Graph using Topological Sorting:
Kahn's algorithm can also be used to detect cycles. It involves calculating the in-degree (number of incoming edges) for each vertex. If at any point the number of processed vertices is less than the total number of vertices, a cycle exists.
Initialize the Graph
- Input: Number of vertices
V
. - Output: An initialized graph with an adjacency list.
- Procedure:
- Create an adjacency list with
V
empty lists. - Initialize each list to represent the neighbors of each vertex.
Add an Edge
- Input: Source vertex
v
and destination vertex w
. - Output: Updated adjacency list with the edge added.
- Procedure:
- Append the destination vertex
w
to the adjacency list of the source vertex v
.
Cycle Detection: Using Kahn's Algorithm (Topological Sorting)
Calculate In-Degree of Each Vertex
- Input: The graph represented as an adjacency list.
- Output: An array
inDegree
where inDegree[i]
is the in-degree of vertex i
. - Procedure:
- Initialize an array
inDegree
of size V
to store the in-degrees of all vertices. - Iterate over each vertex
u
in the graph. - For each adjacent vertex
v
of u
, increment inDegree[v]
by 1.
Enqueue Vertices with 0 In-Degree
- Input: The array
inDegree
. - Output: A queue
q
containing vertices with 0 in-degree. - Procedure:
- Initialize an empty queue
q
. - Iterate over each vertex
u
. - If
inDegree[u]
is 0, enqueue u
into q
.
Perform BFS and Check for Cycles
- Input: The queue
q
, adjacency list adj
, and array inDegree
. - Output: A boolean value indicating if the graph contains a cycle.
- Procedure:
- Initialize a counter
visited
to count the number of visited vertices. - While the queue
q
is not empty:- Dequeue a vertex
u
from q
. - Increment the
visited
counter. - For each adjacent vertex
v
of u
:- Decrement
inDegree[v]
by 1. - If
inDegree[v]
becomes 0, enqueue v
into q
.
- If the
visited
counter is not equal to the number of vertices V
, return true
(the graph contains a cycle). - Otherwise, return
false
.
Implementation cycle detection using Topological Sorting in Java:
Java
// Java Program to detect cycle in a graph
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
class Graph {
private int V; // number of vertices
private ArrayList<ArrayList<Integer> >
adj; // adjacency list
public Graph(int V)
{
this.V = V;
adj = new ArrayList<>(V);
for (int i = 0; i < V; i++) {
adj.add(new ArrayList<>());
}
}
public void addEdge(int v, int w) { adj.get(v).add(w); }
public boolean isCyclic()
{
int[] inDegree
= new int[V]; // stores in-degree of each vertex
Queue<Integer> q
= new LinkedList<>(); // queue to store vertices
// with 0 in-degree
int visited = 0; // count of visited vertices
// calculate in-degree of each vertex
for (int u = 0; u < V; u++) {
for (int v : adj.get(u)) {
inDegree[v]++;
}
}
// enqueue vertices with 0 in-degree
for (int u = 0; u < V; u++) {
if (inDegree[u] == 0) {
q.add(u);
}
}
// BFS traversal
while (!q.isEmpty()) {
int u = q.poll();
visited++;
// reduce in-degree of adjacent vertices
for (int v : adj.get(u)) {
inDegree[v]--;
// if in-degree becomes 0, enqueue the
// vertex
if (inDegree[v] == 0) {
q.add(v);
}
}
}
return visited != V; // if not all vertices are
// visited, there is a cycle
}
}
// Driver code
public class Main {
public static void main(String[] args)
{
Graph g = new Graph(6);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(4, 1);
g.addEdge(4, 5);
g.addEdge(5, 3);
if (g.isCyclic()) {
System.out.println("Graph contains cycle.");
}
else {
System.out.println(
"Graph does not contain cycle.");
}
}
}
OutputGraph does not contain 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.
Similar Reads
Java Program to Find Chromatic Index of Cyclic Graphs Chromatic Index of a graph is the minimum number of colours required to colour the edges of the graph such that any two edges that share the same vertex have different colours. Whereas, the cyclic graph is a graph that contains at least one graph cycle i.e. cyclic means a path from at least one node
3 min read
Java Program to Find a Good Feedback Edge Set in a Graph Feedback edge set is a set of edges where F â E of a directed graph G, whose every cycle must contain at least one edge from F. In simple words, Feedback edge set is a set of edges whose removal from the graph makes the graph directed acyclic graph. Examples: Input: Output: Feedback Edge Set: ( 3 -
4 min read
Java Program to Find a Good Feedback Vertex Set in a Graph A feedback vertex set of a graph is a set of vertices whose removal leaves a graph without cycles. The following graph becomes a Directed acyclic Graph. Examples: Input: Enter the number of vertices: 4 Enter the number of edges: 5 Enter the graph: <Start> <end> 1 2 2 3 3 4 4 1 1 3 Output
8 min read
How to Generate a Random Directed Acyclic Graph for a Given Number of Edges in Java? A Directed Acyclic Graph is a directed graph with no directed cycles. In a directed graph, the edges are connected so that each edge only goes one way. A directed acyclic graph means that the graph is not cyclic, or that it is impossible to start at one point in the graph and traverse the entire gra
5 min read
Java Program to Check Whether Undirected Graph is Connected Using DFS Given an undirected graph, the task is to check if the given graph is connected or not using DFS. A connected graph is a graph that is connected in the sense of a topological space, i.e., there is always a path from any node to any other node in the graph. A graph that is not connected is said to be
3 min read
Java Program to Search an Element in a Circular Linked List A linked list is a kind of linear data structure where each node has a data part and an address part which points to the next node. A circular linked list is a type of linked list where the last node points to the first one, making a circle of nodes. Example: Input : CList = 6->5->4->3->
3 min read
Java Program to Find Minimum Number of Edges to Cut to Make the Graph Disconnected Given a connected graph, the task is to find the minimum number of edges to cut/remove to make the given graph disconnected.A graph is disconnected if there exists at least two vertices of the graph that are not connected by a path. Examples:Input:Output: Minimum Number of Edges to Remove = 2. We ca
4 min read
Java Program to Find a Clique by Using the Technique of the Most Dense Subgraph A clique is a subset of vertices of a graph such that every two distinct vertices in the clique are adjacent. Finding a clique from a graph is an important problem in graph theory and many algorithms have been proposed to solve this problem. The most popular algorithm for finding a clique is the tec
3 min read
Java Program For Checking Linked List With A Loop Is Palindrome Or Not Given a linked list with a loop, the task is to find whether it is palindrome or not. You are not allowed to remove the loop. Examples: Input: 1 -> 2 -> 3 -> 2 /| |/ ------- 1 Output: Palindrome Linked list is 1 2 3 2 1 which is a palindrome. Input: 1 -> 2 -> 3 -> 4 /| |/ ------- 1
4 min read
Implementing Generic Graph in Java Prerequisite: Generic Class We can also use them to code for Graph in Java. The Graph class is implemented using HashMap in Java. As we know HashMap contains a key and a value, we represent nodes as keys and their adjacency list in values in the graph. Illustration: An undirected and unweighted gra
5 min read