Java Implementation
Comprehensive Graph Search Framework
Core Graph Interface
public interface GraphSearchable<T> {
void addVertex(T vertex);
void addEdge(T source, T destination);
List<T> getNeighbors(T vertex);
boolean hasVertex(T vertex);
}
Generic Graph Implementation
Adjacency List Graph
import java.util.*;
public class Graph<T> implements GraphSearchable<T> {
private Map<T, Set<T>> adjacencyList;
public Graph() {
this.adjacencyList = new HashMap<>();
}
@Override
public void addVertex(T vertex) {
adjacencyList.putIfAbsent(vertex, new HashSet<>());
}
@Override
public void addEdge(T source, T destination) {
addVertex(source);
addVertex(destination);
adjacencyList.get(source).add(destination);
}
@Override
public List<T> getNeighbors(T vertex) {
return new ArrayList<>(adjacencyList.getOrDefault(vertex, Collections.emptySet()));
}
@Override
public boolean hasVertex(T vertex) {
return adjacencyList.containsKey(vertex);
}
}
Search Strategy Implementations
Breadth-First Search Strategy
public class BreadthFirstSearchStrategy<T> {
public List<T> search(GraphSearchable<T> graph, T startVertex) {
List<T> visitedNodes = new ArrayList<>();
Queue<T> queue = new LinkedList<>();
Set<T> explored = new HashSet<>();
queue.add(startVertex);
explored.add(startVertex);
while (!queue.isEmpty()) {
T currentVertex = queue.poll();
visitedNodes.add(currentVertex);
for (T neighbor : graph.getNeighbors(currentVertex)) {
if (!explored.contains(neighbor)) {
queue.add(neighbor);
explored.add(neighbor);
}
}
}
return visitedNodes;
}
}
Depth-First Search Strategy
public class DepthFirstSearchStrategy<T> {
public List<T> search(GraphSearchable<T> graph, T startVertex) {
List<T> visitedNodes = new ArrayList<>();
Set<T> explored = new HashSet<>();
dfsRecursive(graph, startVertex, explored, visitedNodes);
return visitedNodes;
}
private void dfsRecursive(GraphSearchable<T> graph, T vertex,
Set<T> explored, List<T> visitedNodes) {
explored.add(vertex);
visitedNodes.add(vertex);
for (T neighbor : graph.getNeighbors(vertex)) {
if (!explored.contains(neighbor)) {
dfsRecursive(graph, neighbor, explored, visitedNodes);
}
}
}
}
Search Strategy Comparison
Strategy |
Memory Usage |
Completeness |
Optimality |
BFS |
O(V) |
Complete |
Optimal for unweighted graphs |
DFS |
O(h), where h is graph height |
Not complete |
Not optimal |
Advanced Search Techniques
Path Finding Implementation
public class PathFinder<T> {
public List<T> findShortestPath(
GraphSearchable<T> graph,
T start,
T end
) {
// Advanced path finding logic
return new ArrayList<>();
}
}
Error Handling and Validation
public class GraphValidator {
public static <T> void validateGraph(GraphSearchable<T> graph) {
Objects.requireNonNull(graph, "Graph cannot be null");
}
}
- Use generics for type flexibility
- Implement efficient data structures
- Consider memory constraints
LabEx Practical Insights
At LabEx, we recommend practicing these implementations to master graph search techniques in real-world scenarios.