mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-08 10:15:51 +08:00
Refactor BipartiteGraphDFS.java, add Junit tests (#5606)
* Refactor `BipartiteGraphDFS.java`, add Junit tests * Update directory * Fix * Add suggested changes * Update BipartiteGraphDFS.java --------- Co-authored-by: Hardvan <Hardvan@users.noreply.github.com> Co-authored-by: Alex Klymenko <alexanderklmn@gmail.com>
This commit is contained in:
@ -676,6 +676,7 @@
|
|||||||
* dynamicarray
|
* dynamicarray
|
||||||
* [DynamicArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java)
|
* [DynamicArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java)
|
||||||
* graphs
|
* graphs
|
||||||
|
* [BipartiteGraphDFSTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java)
|
||||||
* [BoruvkaAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java)
|
* [BoruvkaAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java)
|
||||||
* [DijkstraAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java)
|
* [DijkstraAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java)
|
||||||
* [EdmondsBlossomAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithmTest.java)
|
* [EdmondsBlossomAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithmTest.java)
|
||||||
|
@ -1,23 +1,49 @@
|
|||||||
package com.thealgorithms.datastructures.graphs;
|
package com.thealgorithms.datastructures.graphs;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an adjacency list of a graph adj of V no. of vertices having 0 based
|
* This class provides a method to check if a given undirected graph is bipartite using Depth-First Search (DFS).
|
||||||
* index. Check whether the graph is bipartite or not.
|
* A bipartite graph is a graph whose vertices can be divided into two disjoint sets such that no two vertices
|
||||||
|
* within the same set are adjacent. In other words, all edges must go between the two sets.
|
||||||
*
|
*
|
||||||
* Input : {{0, 1, 0, 1}, {1, 0, 1, 0}, {0, 1, 0, 1}, {1, 0, 1, 0}}
|
* The implementation leverages DFS to attempt to color the graph using two colors. If we can color the graph such
|
||||||
|
* that no two adjacent vertices have the same color, the graph is bipartite.
|
||||||
*
|
*
|
||||||
* Output : YES
|
* Example:
|
||||||
|
* Input (Adjacency Matrix):
|
||||||
|
* {{0, 1, 0, 1},
|
||||||
|
* {1, 0, 1, 0},
|
||||||
|
* {0, 1, 0, 1},
|
||||||
|
* {1, 0, 1, 0}}
|
||||||
|
*
|
||||||
|
* Output: YES (This graph is bipartite)
|
||||||
|
*
|
||||||
|
* Input (Adjacency Matrix):
|
||||||
|
* {{0, 1, 1, 0},
|
||||||
|
* {1, 0, 1, 0},
|
||||||
|
* {1, 1, 0, 1},
|
||||||
|
* {0, 0, 1, 0}}
|
||||||
|
*
|
||||||
|
* Output: NO (This graph is not bipartite)
|
||||||
*/
|
*/
|
||||||
public final class BipartiteGraphDFS {
|
public final class BipartiteGraphDFS {
|
||||||
private BipartiteGraphDFS() {
|
private BipartiteGraphDFS() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to perform DFS and check if the graph is bipartite.
|
||||||
|
*
|
||||||
|
* During DFS traversal, this method attempts to color each vertex in such a way
|
||||||
|
* that no two adjacent vertices share the same color.
|
||||||
|
*
|
||||||
|
* @param v Number of vertices in the graph
|
||||||
|
* @param adj Adjacency list of the graph where each index i contains a list of adjacent vertices
|
||||||
|
* @param color Array to store the color assigned to each vertex (-1 indicates uncolored)
|
||||||
|
* @param node Current vertex being processed
|
||||||
|
* @return True if the graph (or component of the graph) is bipartite, otherwise false
|
||||||
|
*/
|
||||||
private static boolean bipartite(int v, ArrayList<ArrayList<Integer>> adj, int[] color, int node) {
|
private static boolean bipartite(int v, ArrayList<ArrayList<Integer>> adj, int[] color, int node) {
|
||||||
if (color[node] == -1) {
|
if (color[node] == -1) {
|
||||||
color[node] = 1;
|
color[node] = 1;
|
||||||
@ -35,11 +61,16 @@ public final class BipartiteGraphDFS {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to check if the graph is bipartite.
|
||||||
|
*
|
||||||
|
* @param v Number of vertices in the graph
|
||||||
|
* @param adj Adjacency list of the graph
|
||||||
|
* @return True if the graph is bipartite, otherwise false
|
||||||
|
*/
|
||||||
public static boolean isBipartite(int v, ArrayList<ArrayList<Integer>> adj) {
|
public static boolean isBipartite(int v, ArrayList<ArrayList<Integer>> adj) {
|
||||||
// Code here
|
|
||||||
int[] color = new int[v + 1];
|
int[] color = new int[v + 1];
|
||||||
Arrays.fill(color, -1);
|
Arrays.fill(color, -1);
|
||||||
|
|
||||||
for (int i = 0; i < v; i++) {
|
for (int i = 0; i < v; i++) {
|
||||||
if (color[i] == -1) {
|
if (color[i] == -1) {
|
||||||
if (!bipartite(v, adj, color, i)) {
|
if (!bipartite(v, adj, color, i)) {
|
||||||
@ -49,33 +80,4 @@ public final class BipartiteGraphDFS {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
|
|
||||||
int t = Integer.parseInt(read.readLine().trim());
|
|
||||||
while (t-- > 0) {
|
|
||||||
String[] str1 = read.readLine().trim().split(" ");
|
|
||||||
int numVertices = Integer.parseInt(str1[0]);
|
|
||||||
int numEdges = Integer.parseInt(str1[1]);
|
|
||||||
|
|
||||||
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
|
|
||||||
for (int i = 0; i < numVertices; i++) {
|
|
||||||
adj.add(new ArrayList<>());
|
|
||||||
}
|
|
||||||
for (int i = 0; i < numEdges; i++) {
|
|
||||||
String[] str2 = read.readLine().trim().split(" ");
|
|
||||||
int vertexU = Integer.parseInt(str2[0]);
|
|
||||||
int vertexV = Integer.parseInt(str2[1]);
|
|
||||||
adj.get(vertexU).add(vertexV);
|
|
||||||
adj.get(vertexV).add(vertexU);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean ans = isBipartite(numVertices, adj);
|
|
||||||
if (ans) {
|
|
||||||
System.out.println("YES");
|
|
||||||
} else {
|
|
||||||
System.out.println("NO");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.thealgorithms.datastructures.graphs;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class BipartiteGraphDFSTest {
|
||||||
|
|
||||||
|
// Helper method to create an adjacency list from edges
|
||||||
|
private ArrayList<ArrayList<Integer>> createAdjacencyList(int numVertices, int[][] edges) {
|
||||||
|
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
|
||||||
|
for (int i = 0; i < numVertices; i++) {
|
||||||
|
adj.add(new ArrayList<>());
|
||||||
|
}
|
||||||
|
for (int[] edge : edges) {
|
||||||
|
int vertexU = edge[0];
|
||||||
|
int vertexV = edge[1];
|
||||||
|
adj.get(vertexU).add(vertexV);
|
||||||
|
adj.get(vertexV).add(vertexU);
|
||||||
|
}
|
||||||
|
return adj;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBipartiteGraphEvenCycle() {
|
||||||
|
int numVertices = 4;
|
||||||
|
int[][] edges = {{0, 1}, {1, 2}, {2, 3}, {3, 0}}; // Even cycle
|
||||||
|
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
|
||||||
|
assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (even cycle)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBipartiteGraphOddCycle() {
|
||||||
|
int numVertices = 5;
|
||||||
|
int[][] edges = {{0, 1}, {1, 2}, {2, 0}, {1, 3}, {3, 4}}; // Odd cycle
|
||||||
|
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
|
||||||
|
assertFalse(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should not be bipartite (odd cycle)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBipartiteGraphDisconnected() {
|
||||||
|
int numVertices = 6;
|
||||||
|
int[][] edges = {{0, 1}, {2, 3}, {4, 5}}; // Disconnected bipartite graphs
|
||||||
|
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
|
||||||
|
assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (disconnected)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBipartiteGraphSingleVertex() {
|
||||||
|
int numVertices = 1;
|
||||||
|
int[][] edges = {}; // Single vertex, no edges
|
||||||
|
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
|
||||||
|
assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (single vertex)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBipartiteGraphCompleteBipartite() {
|
||||||
|
int numVertices = 4;
|
||||||
|
int[][] edges = {{0, 2}, {0, 3}, {1, 2}, {1, 3}}; // K2,2 (Complete bipartite graph)
|
||||||
|
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
|
||||||
|
assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (complete bipartite)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBipartiteGraphNonBipartite() {
|
||||||
|
int numVertices = 3;
|
||||||
|
int[][] edges = {{0, 1}, {1, 2}, {2, 0}}; // Triangle (odd cycle)
|
||||||
|
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
|
||||||
|
assertFalse(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should not be bipartite (triangle)");
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user