A comprehensive Java library implementing classic graph algorithms with complete test coverage and performance benchmarks.
Note
Project Purpose: This is a recreational and educational library focused on clean implementations of fundamental graph algorithms. Auxiliary tasksβsuch as documentation, comprehensive testing, and refactoringβare automated via AI assistants, allowing the developer to concentrate on algorithmic logic.
The library follows object-oriented design with a focus on extensibility and type safety.
graphs.Graph(Base Abstract Class): Manages core structure (Vertices, Edges, Adjacency).- Encapsulation: Internal attributes (
vertices,edges,adjacencyMap) areprotected.- Internal Use: Subclasses access directly for optimal performance.
- External Use: Clients use
getVertices()andgetEdges(), which return immutable views for safety.
- Subclasses:
UndirectedGraph: Undirected graphs with bipartite matching, Eulerian paths, biconnectivity.Digraph: Directed graphs with topological sort, strong connectivity, Eulerian circuits.
graph-algorithms/
βββ src/
β βββ graphs/ # Core algorithms (Graph, UndirectedGraph, Digraph)
β βββ utils/ # Utilities (GraphGenerator, Builders)
β βββ tests/ # Comprehensive test suite (RegressionTests, StressTests)
βββ inputs/
β βββ test/ # Graph data files for automated tests (.txt format)
β βββ user/ # Your custom graph files (place .txt files here)
βββ scripts/ # Build and test scripts
βββ out/ # Compiled bytecode (gitignored)
βββ README.md
git clone <repository-url>
cd graph-algorithmsNo external dependencies requiredβjust Java 17+.
Option 1: Manual Creation
import graphs.*;
public class Main {
public static void main(String[] args) {
UndirectedGraph g = new UndirectedGraph();
Graph.Vertex a = g.addVertex("A");
Graph.Vertex b = g.addVertex("B");
Graph.Vertex c = g.addVertex("C");
g.addEdge(a, b);
g.addEdge(b, c);
System.out.println("Vertices: " + g.getVertices());
System.out.println("Is Connected: " + g.isConnected());
}
}Option 2: Load from File (Builders)
import graphs.*;
import utils.Builders;
public class Main {
public static void main(String[] args) {
// Load from file (edge-list format)
UndirectedGraph g = Builders.undirectedGraphBuilder("inputs/user/my_graph.txt");
Digraph d = Builders.digraphBuilder("inputs/user/my_digraph.txt");
// Run algorithms
System.out.println("Bipartite: " + g.isBipartite());
System.out.println("Has Cycle: " + d.hasCycles());
// Max matching (Hopcroft-Karp O(EβV))
var matching = g.maxMatching();
System.out.println("Max Matching Size: " + matching.size());
}
}π Where to put your graph files: Place your
.txtfiles ininputs/user/(created for you). This directory is separate from test data and gitignored for your custom graphs.
javac -d out -cp src src/Main.java
java -cp out MainGraph files in inputs/test/ use a simple edge-list format compatible with CS Academy Graph Editor:
Undirected graph (u_*.txt):
1 2
2 3
3 1
Directed graph (d_*.txt):
1 2
2 3
3 1
Tip: Visualize any
.txtfile by copying its contents to the CS Academy Graph Editor!
./scripts/run_tests.sh./scripts/run_stress_tests.shNote: Stress tests run with -Xss32m -Xmx2G for deep recursion and large graphs.
Note
All algorithms currently implemented in this library are deterministic and run in polynomial time relative to the number of vertices (
| Algorithm | Complexity | Description |
|---|---|---|
| BFS | Ξ(V + E) | Breadth-First Search for distances |
| Tree BFS | Ξ(V + E) | BFS spanning tree |
| Algorithm | Complexity | Description |
|---|---|---|
| Connected Components (DFS) | Ξ(V + E) | Find all connected components |
| Bridges (Tarjan) | Ξ(V + E) | Find critical edges |
| Articulation Points (Tarjan) | Ξ(V + E) | Find critical vertices |
| Biconnectivity | Ξ(V + E) | Check 2-edge/2-vertex connectivity |
| Biconnected Components | Ξ(V + E) | Decompose into biconnected parts |
| Algorithm | Complexity | Description |
|---|---|---|
| Cycle Detection (DFS) | O(V + E) | Check for cycles |
| Eulerian Circuit/Trail (Hierholzer) | Ξ(V + E) | Find Eulerian paths efficiently |
| Eulerian Circuit/Trail (Fleury) | O(EΒ²) | Classical approach |
| Algorithm | Complexity | Description |
|---|---|---|
| Bipartite Check (BFS) | O(V + E) | 2-coloring verification |
| Max Matching (Hopcroft-Karp) | O(EβV) | Maximum bipartite matching |
| Min Vertex Cover (KΓΆnig) | O(EβV) | Minimum vertex cover via matching |
| Max Independent Set (Gallai) | O(EβV) | Maximum independent set |
| Algorithm | Complexity | Description |
|---|---|---|
| Cycle Detection (DFS) | O(V + E) | Detect directed cycles |
| Topological Sort (Kahn) | Ξ(V + E) | Linear ordering of DAG |
| Tree Check | O(V + E) | Verify directed tree structure |
| Algorithm | Complexity | Description |
|---|---|---|
| SCC (Kosaraju-Sharir) | Ξ(V + E) | Two-pass DFS approach |
| SCC (Tarjan) | Ξ(V + E) | Single-pass DFS with lowlink |
| Algorithm | Complexity | Description |
|---|---|---|
| Eulerian Circuit/Trail (Hierholzer) | Ξ(V + E) | Directed Eulerian paths |
| Algorithm | Complexity | Description |
|---|---|---|
| Standard Bipartite (2-coloring) | O(V + E) | Underlying undirected bipartition |
| Source-Sink Bipartite | Ξ(E) | Strict in/out degree separation |
- 20 test methods covering all 41 public algorithms
- 24 graph files including edge cases (disconnected, complete, cycles, DAGs)
- 100% method coverage with both success and failure cases
- Stress tests on graphs with 5,000+ vertices
- Javadoc complexity annotations: Every public method documents its algorithm name and Big-O complexity
- Multiple implementations: Compare Hierholzer vs Fleury, Kosaraju vs Tarjan
- Theoretical validations: KΓΆnig's Theorem, Gallai's Identity verified in tests
- Implement in appropriate class (
UndirectedGraphorDigraph) - Add Javadoc with complexity:
@complexity Ξ(V + E) time, O(V) space - Add test in
RegressionTests.java - Run test suite:
./scripts/run_tests.sh
- Clean implementations without verbose comments
- Complexity documentation via Javadoc only
- Immutable external interfaces, mutable internal for performance