Cycle Detection कैसे करें
def has_cycle(node, parent, visited):
visited.add(node)
for neighbor in graph[node]:
if neighbor not in visited:
if has_cycle(neighbor, node, visited):
return True
elif neighbor != parent:
return True
return False
Cycle in Graph
एक cycle मौजूद है जब आप किसी vertex से शुरू कर सकते हैं, edges follow कर सकते हैं, और आखिरकार उसी vertex पर बिना किसी edge दोहराए वापस आ सकते हैं — एक circular hallway जैसा जो आखिरकार वापस वहां ले जाता है जहां से आप शुरू हुए।
उदाहरण: Cycle in Graph
#include <iostream>
using namespace std;
int main() {
int path[] = {0, 1, 2, 0};
cout << "Path 0->1->2->0 returns to start without repeating an edge: cycle found";
return 0;
}
public class Main {
public static void main(String[] args) {
int[] path = {0, 1, 2, 0};
System.out.println("Path 0->1->2->0 returns to start without repeating an edge: cycle found");
}
}
path = [0, 1, 2, 0]
print("Path 0->1->2->0 returns to start without repeating an edge: cycle found")
#include <stdio.h>
int main() {
int path[] = {0, 1, 2, 0};
printf("Path 0->1->2->0 returns to start without repeating an edge: cycle found");
return 0;
}
Login to try C/C++/Java code in the editor
Visited Vertices
Traversal के दौरान हर vertex को visited मार्क करना आपको एक cycle पहचानने देता है जैसे ही आप उस vertex तक पहुंचें जो पहले current exploration में visited हो चुका है, पहली बार के बजाय।
उदाहरण: Visited Vertices
#include <iostream>
using namespace std;
int adj[3][1] = {{1},{2},{0}};
bool visited[3] = {false};
bool dfs(int u) {
if (visited[u]) return true;
visited[u] = true;
return dfs(adj[u][0]);
}
int main() {
cout << (dfs(0) ? "Cycle found: revisited an already-visited vertex" : "No cycle");
return 0;
}
public class Main {
static int[][] adj = {{1},{2},{0}};
static boolean[] visited = new boolean[3];
static boolean dfs(int u) {
if (visited[u]) return true;
visited[u] = true;
return dfs(adj[u][0]);
}
public static void main(String[] args) {
System.out.println(dfs(0) ? "Cycle found: revisited an already-visited vertex" : "No cycle");
}
}
adj = [[1],[2],[0]]
visited = [False]*3
def dfs(u):
if visited[u]:
return True
visited[u] = True
return dfs(adj[u][0])
print("Cycle found: revisited an already-visited vertex" if dfs(0) else "No cycle")
#include <stdio.h>
int adj[3][1] = {{1},{2},{0}};
int visited[3] = {0};
int dfs(int u) {
if (visited[u]) return 1;
visited[u] = 1;
return dfs(adj[u][0]);
}
int main() {
printf(dfs(0) ? "Cycle found: revisited an already-visited vertex" : "No cycle");
return 0;
}
Login to try C/C++/Java code in the editor
Undirected Graph
एक undirected graph में आप जिस भी edge पर आते हैं वह तुरंत उस vertex को 'already visited' जैसा दिखाता है जहां से आप आए, इसलिए DFS को immediate parent की वापसी वाले edge को explicitly नज़रअंदाज़ करना चाहिए — नहीं तो हर single edge को एक false cycle के रूप में flag किया जाएगा।
उदाहरण: Undirected Graph
#include <iostream>
using namespace std;
int adj[3][2] = {{1,2},{0,2},{0,1}};
int adjCount[3] = {2,2,2};
bool visited[3] = {false};
bool dfs(int u, int parent) {
visited[u] = true;
for (int i = 0; i < adjCount[u]; i++) {
int v = adj[u][i];
if (v == parent) continue;
if (visited[v]) return true;
if (dfs(v, u)) return true;
}
return false;
}
int main() {
cout << (dfs(0, -1) ? "Cycle found (ignoring the edge back to parent)" : "No cycle");
return 0;
}
public class Main {
static int[][] adj = {{1,2},{0,2},{0,1}};
static boolean[] visited = new boolean[3];
static boolean dfs(int u, int parent) {
visited[u] = true;
for (int v : adj[u]) {
if (v == parent) continue;
if (visited[v]) return true;
if (dfs(v, u)) return true;
}
return false;
}
public static void main(String[] args) {
System.out.println(dfs(0, -1) ? "Cycle found (ignoring the edge back to parent)" : "No cycle");
}
}
adj = [[1,2],[0,2],[0,1]]
visited = [False]*3
def dfs(u, parent):
visited[u] = True
for v in adj[u]:
if v == parent:
continue
if visited[v] or dfs(v, u):
return True
return False
print("Cycle found (ignoring the edge back to parent)" if dfs(0, -1) else "No cycle")
#include <stdio.h>
int adj[3][2] = {{1,2},{0,2},{0,1}};
int visited[3] = {0};
int dfs(int u, int parent) {
visited[u] = 1;
for (int i = 0; i < 2; i++) {
int v = adj[u][i];
if (v == parent) continue;
if (visited[v] || dfs(v, u)) return 1;
}
return 0;
}
int main() {
printf(dfs(0, -1) ? "Cycle found (ignoring the edge back to parent)" : "No cycle");
return 0;
}
Login to try C/C++/Java code in the editor
Directed Graph
Directed graphs को visited से आगे एक दूसरा marker चाहिए: एक vertex को current recursion path के हिस्से (in-progress) के रूप में flag किया जाना चाहिए, क्योंकि एक अलग branch में पहले खत्म हुए vertex को फिर से visit करना एक cycle नहीं है, लेकिन अब भी current path पर एक को revisit करना है।
उदाहरण: Directed Graph
#include <iostream>
using namespace std;
int adj[3][1] = {{1},{2},{0}};
bool visited[3] = {false}, inStack[3] = {false};
bool dfs(int u) {
visited[u] = true; inStack[u] = true;
int v = adj[u][0];
if (inStack[v]) return true;
if (!visited[v] && dfs(v)) return true;
inStack[u] = false;
return false;
}
int main() {
cout << (dfs(0) ? "Cycle: vertex still in current recursion path" : "No cycle");
return 0;
}
public class Main {
static int[][] adj = {{1},{2},{0}};
static boolean[] visited = new boolean[3], inStack = new boolean[3];
static boolean dfs(int u) {
visited[u] = true; inStack[u] = true;
int v = adj[u][0];
if (inStack[v]) return true;
if (!visited[v] && dfs(v)) return true;
inStack[u] = false;
return false;
}
public static void main(String[] args) {
System.out.println(dfs(0) ? "Cycle: vertex still in current recursion path" : "No cycle");
}
}
adj = [[1],[2],[0]]
visited = [False]*3
in_stack = [False]*3
def dfs(u):
visited[u] = True
in_stack[u] = True
v = adj[u][0]
if in_stack[v]:
return True
if not visited[v] and dfs(v):
return True
in_stack[u] = False
return False
print("Cycle: vertex still in current recursion path" if dfs(0) else "No cycle")
#include <stdio.h>
int adj[3][1] = {{1},{2},{0}};
int visited[3] = {0}, inStack[3] = {0};
int dfs(int u) {
visited[u] = 1; inStack[u] = 1;
int v = adj[u][0];
if (inStack[v]) return 1;
if (!visited[v] && dfs(v)) return 1;
inStack[u] = 0;
return 0;
}
int main() {
printf(dfs(0) ? "Cycle: vertex still in current recursion path" : "No cycle");
return 0;
}
Login to try C/C++/Java code in the editor
Why Detect Cycles
Cycles detect करना practical कारणों से मायने रखता है: software packages के बीच एक circular dependency एक infinite build loop का कारण बनेगी, और एक course-prerequisite graph में एक cycle हर requirement को कभी satisfy करना असंभव बना देगी।
उदाहरण: Why Detect Cycles
#include <iostream>
using namespace std;
int main() {
cout << "Package A depends on B depends on A: circular dependency, build loops forever";
return 0;
}
public class Main {
public static void main(String[] args) {
System.out.println("Package A depends on B depends on A: circular dependency, build loops forever");
}
}
print("Package A depends on B depends on A: circular dependency, build loops forever")
#include <stdio.h>
int main() {
printf("Package A depends on B depends on A: circular dependency, build loops forever");
return 0;
}
Login to try C/C++/Java code in the editor
- एक directed graph पर undirected algorithm उपयोग करना, इसलिए अलग paths से दो बार पहुंचा एक vertex एक cycle के रूप में report होता है।
- एक undirected graph में, parent को एक visited neighbor की तरह treat करना, जो हर edge के लिए एक cycle report करता है।
- एक directed graph में, call return होने पर recursion stack से एक vertex unmark करना भूल जाना।
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: