From 19c492d4b559606d5c6d6b82817f9ce15fc4b6c4 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Sun, 6 Oct 2024 12:38:36 +0530 Subject: [PATCH 1/5] Refactor `BipartiteGraphDFS.java`, add Junit tests --- .../graphs/BipartiteGraphDFS.java | 30 +++++++- .../graphs/BipartiteGraphDFSTest.java | 73 +++++++++++++++++++ 2 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java index e8d2b8fd0a04..16ecf0091adb 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java @@ -7,17 +7,27 @@ import java.util.Arrays; /** - * Given an adjacency list of a graph adj of V no. of vertices having 0 based - * index. Check whether the graph is bipartite or not. + * This class provides a method to check if a given graph is bipartite using Depth-First Search (DFS). + * A bipartite graph is a graph whose vertices can be divided into two disjoint sets such that no two graph vertices + * within the same set are adjacent. * + * Example: * Input : {{0, 1, 0, 1}, {1, 0, 1, 0}, {0, 1, 0, 1}, {1, 0, 1, 0}} - * * Output : YES */ public final class BipartiteGraphDFS { private BipartiteGraphDFS() { } + /** + * Helper method to perform DFS and check if the graph is bipartite. + * + * @param v Number of vertices in the graph + * @param adj Adjacency list of the graph + * @param color Array to store colors assigned to vertices + * @param node Current node being processed + * @return True if the graph is bipartite, otherwise false + */ private static boolean bipartite(int v, ArrayList> adj, int[] color, int node) { if (color[node] == -1) { color[node] = 1; @@ -35,11 +45,17 @@ private static boolean bipartite(int v, ArrayList> adj, int[] 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> adj) { // Code here int[] color = new int[v + 1]; Arrays.fill(color, -1); - for (int i = 0; i < v; i++) { if (color[i] == -1) { if (!bipartite(v, adj, color, i)) { @@ -50,6 +66,12 @@ public static boolean isBipartite(int v, ArrayList> adj) { return true; } + /** + * Main method to read input and check if the graph is bipartite. + * + * @param args Command line arguments + * @throws IOException If an I/O error occurs + */ public static void main(String[] args) throws IOException { BufferedReader read = new BufferedReader(new InputStreamReader(System.in)); int t = Integer.parseInt(read.readLine().trim()); diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java new file mode 100644 index 000000000000..30e37889fb80 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java @@ -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 org.junit.jupiter.api.Test; +import java.util.ArrayList; + +public class BipartiteGraphDFSTest { + + // Helper method to create an adjacency list from edges + private ArrayList> createAdjacencyList(int numVertices, int[][] edges) { + ArrayList> 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> 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> 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> 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> 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> 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> adj = createAdjacencyList(numVertices, edges); + assertFalse(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should not be bipartite (triangle)"); + } +} From 635975fde59f4c65963f024955e9022c85dccc44 Mon Sep 17 00:00:00 2001 From: Hardvan Date: Sun, 6 Oct 2024 07:08:54 +0000 Subject: [PATCH 2/5] Update directory --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 1bad5d3b98a3..815283e0c11f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -671,6 +671,7 @@ * dynamicarray * [DynamicArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java) * 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) * [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) From 8545d7832fe19db0c99c80364b92a4454776d908 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Sun, 6 Oct 2024 12:41:49 +0530 Subject: [PATCH 3/5] Fix --- .../datastructures/graphs/BipartiteGraphDFSTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java index 30e37889fb80..75fa6adc3014 100644 --- a/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java +++ b/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java @@ -3,8 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; import java.util.ArrayList; +import org.junit.jupiter.api.Test; public class BipartiteGraphDFSTest { @@ -26,7 +26,7 @@ private ArrayList> createAdjacencyList(int numVertices, int[] @Test public void testBipartiteGraphEvenCycle() { int numVertices = 4; - int[][] edges = { {0, 1}, {1, 2}, {2, 3}, {3, 0} }; // Even cycle + int[][] edges = {{0, 1}, {1, 2}, {2, 3}, {3, 0}}; // Even cycle ArrayList> adj = createAdjacencyList(numVertices, edges); assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (even cycle)"); } @@ -34,7 +34,7 @@ public void testBipartiteGraphEvenCycle() { @Test public void testBipartiteGraphOddCycle() { int numVertices = 5; - int[][] edges = { {0, 1}, {1, 2}, {2, 0}, {1, 3}, {3, 4} }; // Odd cycle + int[][] edges = {{0, 1}, {1, 2}, {2, 0}, {1, 3}, {3, 4}}; // Odd cycle ArrayList> adj = createAdjacencyList(numVertices, edges); assertFalse(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should not be bipartite (odd cycle)"); } @@ -42,7 +42,7 @@ public void testBipartiteGraphOddCycle() { @Test public void testBipartiteGraphDisconnected() { int numVertices = 6; - int[][] edges = { {0, 1}, {2, 3}, {4, 5} }; // Disconnected bipartite graphs + int[][] edges = {{0, 1}, {2, 3}, {4, 5}}; // Disconnected bipartite graphs ArrayList> adj = createAdjacencyList(numVertices, edges); assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (disconnected)"); } @@ -58,7 +58,7 @@ public void testBipartiteGraphSingleVertex() { @Test public void testBipartiteGraphCompleteBipartite() { int numVertices = 4; - int[][] edges = { {0, 2}, {0, 3}, {1, 2}, {1, 3} }; // K2,2 (Complete bipartite graph) + int[][] edges = {{0, 2}, {0, 3}, {1, 2}, {1, 3}}; // K2,2 (Complete bipartite graph) ArrayList> adj = createAdjacencyList(numVertices, edges); assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (complete bipartite)"); } @@ -66,7 +66,7 @@ public void testBipartiteGraphCompleteBipartite() { @Test public void testBipartiteGraphNonBipartite() { int numVertices = 3; - int[][] edges = { {0, 1}, {1, 2}, {2, 0} }; // Triangle (odd cycle) + int[][] edges = {{0, 1}, {1, 2}, {2, 0}}; // Triangle (odd cycle) ArrayList> adj = createAdjacencyList(numVertices, edges); assertFalse(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should not be bipartite (triangle)"); } From c69f42c8b25c704484cbba118c3fd45daa1dca8c Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Sun, 6 Oct 2024 19:37:14 +0530 Subject: [PATCH 4/5] Add suggested changes --- .../graphs/BipartiteGraphDFS.java | 73 +++++++------------ 1 file changed, 28 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java index 16ecf0091adb..89c65a28b3db 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java @@ -7,13 +7,29 @@ import java.util.Arrays; /** - * This class provides a method to check if a given graph is bipartite using Depth-First Search (DFS). - * A bipartite graph is a graph whose vertices can be divided into two disjoint sets such that no two graph vertices - * within the same set are adjacent. + * This class provides a method to check if a given undirected graph is bipartite using Depth-First Search (DFS). + * 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. + * + * 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. * * Example: - * Input : {{0, 1, 0, 1}, {1, 0, 1, 0}, {0, 1, 0, 1}, {1, 0, 1, 0}} - * Output : YES + * 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 { private BipartiteGraphDFS() { @@ -22,11 +38,14 @@ 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 - * @param color Array to store colors assigned to vertices - * @param node Current node being processed - * @return True if the graph is bipartite, otherwise false + * @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> adj, int[] color, int node) { if (color[node] == -1) { @@ -53,7 +72,6 @@ private static boolean bipartite(int v, ArrayList> adj, int[] * @return True if the graph is bipartite, otherwise false */ public static boolean isBipartite(int v, ArrayList> adj) { - // Code here int[] color = new int[v + 1]; Arrays.fill(color, -1); for (int i = 0; i < v; i++) { @@ -65,39 +83,4 @@ public static boolean isBipartite(int v, ArrayList> adj) { } return true; } - - /** - * Main method to read input and check if the graph is bipartite. - * - * @param args Command line arguments - * @throws IOException If an I/O error occurs - */ - 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> 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"); - } - } - } } From 177658016713ec856ba90980e0b7c668cee42055 Mon Sep 17 00:00:00 2001 From: Hardik Pawar <97388607+Hardvan@users.noreply.github.com> Date: Sun, 6 Oct 2024 23:28:09 +0530 Subject: [PATCH 5/5] Update BipartiteGraphDFS.java --- .../thealgorithms/datastructures/graphs/BipartiteGraphDFS.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java index 89c65a28b3db..15ae5225533c 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java @@ -1,8 +1,5 @@ package com.thealgorithms.datastructures.graphs; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays;