Skip to content

Refactor BipartiteGraphDFS.java, add Junit tests #5606

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,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)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,49 @@
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;

/**
* 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 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.
*
* 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 {
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) {
if (color[node] == -1) {
color[node] = 1;
Expand All @@ -35,11 +61,16 @@ private static boolean bipartite(int v, ArrayList<ArrayList<Integer>> 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<ArrayList<Integer>> 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)) {
Expand All @@ -49,33 +80,4 @@ public static boolean isBipartite(int v, ArrayList<ArrayList<Integer>> adj) {
}
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");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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)");
}
}