Bael 2950 graph has cycle check for directed graphs (#7088)
* BAEL-2950 : Graph Check If Cycle Exists * BAEL-2950 : Minor Refactoring * BAEL-2950 Cycle detection * BAEL-2950 : Renaming unit test file
This commit is contained in:
parent
aa4f6873cb
commit
51e050ae85
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.algorithms.graphcycledetection.domain;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Graph {
|
||||||
|
|
||||||
|
private List<Vertex> vertices;
|
||||||
|
|
||||||
|
public Graph() {
|
||||||
|
this.vertices = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Graph(List<Vertex> vertices) {
|
||||||
|
this.vertices = vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addVertex(Vertex vertex) {
|
||||||
|
this.vertices.add(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEdge(Vertex from, Vertex to) {
|
||||||
|
from.addNeighbour(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasCycle() {
|
||||||
|
for (Vertex vertex : vertices) {
|
||||||
|
if (!vertex.isVisited() && hasCycle(vertex)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasCycle(Vertex sourceVertex) {
|
||||||
|
sourceVertex.setBeingVisited(true);
|
||||||
|
|
||||||
|
for (Vertex neighbour : sourceVertex.getAdjacencyList()) {
|
||||||
|
if (neighbour.isBeingVisited()) {
|
||||||
|
// backward edge exists
|
||||||
|
return true;
|
||||||
|
} else if (!neighbour.isVisited() && hasCycle(neighbour)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceVertex.setBeingVisited(false);
|
||||||
|
sourceVertex.setVisited(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.algorithms.graphcycledetection.domain;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Vertex {
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
private boolean visited;
|
||||||
|
|
||||||
|
private boolean beingVisited;
|
||||||
|
|
||||||
|
private List<Vertex> adjacencyList;
|
||||||
|
|
||||||
|
public Vertex(String label) {
|
||||||
|
this.label = label;
|
||||||
|
this.adjacencyList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVisited() {
|
||||||
|
return visited;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisited(boolean visited) {
|
||||||
|
this.visited = visited;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBeingVisited() {
|
||||||
|
return beingVisited;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBeingVisited(boolean beingVisited) {
|
||||||
|
this.beingVisited = beingVisited;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Vertex> getAdjacencyList() {
|
||||||
|
return adjacencyList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdjacencyList(List<Vertex> adjacencyList) {
|
||||||
|
this.adjacencyList = adjacencyList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addNeighbour(Vertex adjacent) {
|
||||||
|
this.adjacencyList.add(adjacent);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.algorithms.graphcycledetection;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.algorithms.graphcycledetection.domain.Graph;
|
||||||
|
import com.baeldung.algorithms.graphcycledetection.domain.Vertex;
|
||||||
|
|
||||||
|
public class GraphCycleDetectionUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGraph_whenCycleExists_thenReturnTrue() {
|
||||||
|
|
||||||
|
Vertex vertexA = new Vertex("A");
|
||||||
|
Vertex vertexB = new Vertex("B");
|
||||||
|
Vertex vertexC = new Vertex("C");
|
||||||
|
Vertex vertexD = new Vertex("D");
|
||||||
|
|
||||||
|
Graph graph = new Graph();
|
||||||
|
graph.addVertex(vertexA);
|
||||||
|
graph.addVertex(vertexB);
|
||||||
|
graph.addVertex(vertexC);
|
||||||
|
graph.addVertex(vertexD);
|
||||||
|
|
||||||
|
graph.addEdge(vertexA, vertexB);
|
||||||
|
graph.addEdge(vertexB, vertexC);
|
||||||
|
graph.addEdge(vertexC, vertexA);
|
||||||
|
graph.addEdge(vertexD, vertexC);
|
||||||
|
|
||||||
|
assertTrue(graph.hasCycle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGraph_whenNoCycleExists_thenReturnFalse() {
|
||||||
|
|
||||||
|
Vertex vertexA = new Vertex("A");
|
||||||
|
Vertex vertexB = new Vertex("B");
|
||||||
|
Vertex vertexC = new Vertex("C");
|
||||||
|
Vertex vertexD = new Vertex("D");
|
||||||
|
|
||||||
|
Graph graph = new Graph();
|
||||||
|
graph.addVertex(vertexA);
|
||||||
|
graph.addVertex(vertexB);
|
||||||
|
graph.addVertex(vertexC);
|
||||||
|
graph.addVertex(vertexD);
|
||||||
|
|
||||||
|
graph.addEdge(vertexA, vertexB);
|
||||||
|
graph.addEdge(vertexB, vertexC);
|
||||||
|
graph.addEdge(vertexA, vertexC);
|
||||||
|
graph.addEdge(vertexD, vertexC);
|
||||||
|
|
||||||
|
assertFalse(graph.hasCycle());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue