Skip to content

Commit 02e49e7

Browse files
authored
Optimize BreadthFirstSearch implementation with bug fixes and improvements
- Fix potential infinite loop by adding cycle detection using HashSet - Add null value and null node handling for better robustness - Optimize visited node lookups from O(n) to O(1) using HashSet - Clear previous search results for multiple search support - Add defensive copying in getVisited() to prevent external state modification - Improve code organization and documentation - Add consistent node visitation handling - Fix root node visitation order inconsistency - Prevent redundant node processing
1 parent 33dee07 commit 02e49e7

File tree

1 file changed

+37
-17
lines changed

1 file changed

+37
-17
lines changed

src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,67 @@
33
import com.thealgorithms.datastructures.Node;
44
import java.util.ArrayDeque;
55
import java.util.ArrayList;
6+
import java.util.HashSet;
67
import java.util.List;
78
import java.util.Optional;
89
import java.util.Queue;
10+
import java.util.Set;
911

1012
/**
11-
* @author: caos321
12-
* @date: 31 October 2021 (Sunday)
13-
* @wiki: https://en.wikipedia.org/wiki/Breadth-first_search
13+
* Breadth-First Search implementation for tree/graph traversal.
14+
* @author caos321
15+
* @co-author manishraj27
16+
* @see <a href="https://en.wikipedia.org/wiki/Breadth-first_search">Breadth-first search</a>
1417
*/
1518
public class BreadthFirstSearch<T> {
1619

1720
private final List<T> visited = new ArrayList<>();
21+
private final Set<T> visitedSet = new HashSet<>();
1822

19-
public Optional<Node<T>> search(final Node<T> node, final T value) {
20-
if (node == null) {
23+
/**
24+
* Performs a breadth-first search to find a node with the given value.
25+
*
26+
* @param root The root node to start the search from
27+
* @param value The value to search for
28+
* @return Optional containing the found node, or empty if not found
29+
*/
30+
public Optional<Node<T>> search(final Node<T> root, final T value) {
31+
if (value == null || root == null) {
2132
return Optional.empty();
2233
}
23-
if (node.getValue().equals(value)) {
24-
// add root node to visited
25-
visited.add(value);
26-
return Optional.of(node);
27-
}
28-
visited.add(node.getValue());
2934

30-
Queue<Node<T>> queue = new ArrayDeque<>(node.getChildren());
35+
visited.clear();
36+
visitedSet.clear();
37+
38+
Queue<Node<T>> queue = new ArrayDeque<>();
39+
queue.offer(root);
40+
visitedSet.add(root.getValue());
41+
visited.add(root.getValue());
3142

3243
while (!queue.isEmpty()) {
3344
final Node<T> current = queue.poll();
34-
visited.add(current.getValue());
3545

36-
if (current.getValue().equals(value)) {
46+
if (value.equals(current.getValue())) {
3747
return Optional.of(current);
3848
}
3949

40-
queue.addAll(current.getChildren());
50+
for (Node<T> child : current.getChildren()) {
51+
if (child != null && !visitedSet.contains(child.getValue())) {
52+
queue.offer(child);
53+
visitedSet.add(child.getValue());
54+
visited.add(child.getValue());
55+
}
56+
}
4157
}
42-
4358
return Optional.empty();
4459
}
4560

61+
/**
62+
* Returns the list of nodes in the order they were visited.
63+
*
64+
* @return A new list containing the visited nodes
65+
*/
4666
public List<T> getVisited() {
47-
return visited;
67+
return new ArrayList<>(visited);
4868
}
4969
}

0 commit comments

Comments
 (0)