diff --git a/src/main/java/com/thealgorithms/searches/BinarySearch.java b/src/main/java/com/thealgorithms/searches/BinarySearch.java
index 7a5361b280ea..626f3a069e80 100644
--- a/src/main/java/com/thealgorithms/searches/BinarySearch.java
+++ b/src/main/java/com/thealgorithms/searches/BinarySearch.java
@@ -3,32 +3,39 @@
import com.thealgorithms.devutils.searches.SearchAlgorithm;
/**
- * Binary Search Algorithm Implementation
+ * Binary Search Algorithm Implementation.
*
- *
Binary search is one of the most efficient searching algorithms for finding a target element
- * in a SORTED array. It works by repeatedly dividing the search space in half, eliminating half of
- * the remaining elements in each step.
+ *
Binary search is an efficient algorithm for finding a target element in a sorted array. It
+ * repeatedly divides the search range in half and compares the target value with the middle
+ * element.
*
- *
IMPORTANT: This algorithm ONLY works correctly if the input array is sorted in ascending
- * order.
+ *
The algorithm works as follows:
+ *
+ * - Start with the entire sorted array.
+ * - Find the middle element of the current search range.
+ * - If the middle element is equal to the target, return its index.
+ * - If the target is smaller than the middle element, continue searching the left half.
+ * - If the target is greater than the middle element, continue searching the right half.
+ * - If the search range becomes empty, return {@code -1}.
+ *
*
- * Algorithm Overview: 1. Start with the entire array (left = 0, right = array.length - 1) 2.
- * Calculate the middle index 3. Compare the middle element with the target: - If middle element
- * equals target: Found! Return the index - If middle element is less than target: Search the right
- * half - If middle element is greater than target: Search the left half 4. Repeat until element is
- * found or search space is exhausted
+ *
Example:
+ *
+ * array = [1, 3, 5, 7, 9, 11]
+ * key = 7
+ * result = 3
+ *
*
- * Performance Analysis: - Best-case time complexity: O(1) - Element found at middle on first
- * try - Average-case time complexity: O(log n) - Most common scenario - Worst-case time
- * complexity: O(log n) - Element not found or at extreme end - Space complexity: O(1) - Only uses
- * a constant amount of extra space
+ *
Time Complexity:
+ *
+ * - Best case: O(1), when the key is found at the middle index.
+ * - Average case: O(log n), because the search range is divided in half each time.
+ * - Worst case: O(log n), when the key is not present or is found after repeated halving.
+ *
*
- * Example Walkthrough: Array: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] Target: 7
+ *
Space Complexity: O(log n), due to the recursive call stack.
*
- *
Step 1: left=0, right=9, mid=4, array[4]=9 (9 > 7, search left half) Step 2: left=0,
- * right=3, mid=1, array[1]=3 (3 < 7, search right half) Step 3: left=2, right=3, mid=2,
- * array[2]=5 (5 < 7, search right half) Step 4: left=3, right=3, mid=3, array[3]=7 (Found!
- * Return index 3)
+ *
Note: The input array must be sorted in ascending order.
*
* @author Varun Upadhyay (https://github.com/varunu28)
* @author Podshivalov Nikita (https://github.com/nikitap492)
@@ -38,89 +45,43 @@
class BinarySearch implements SearchAlgorithm {
/**
- * Generic method to perform binary search on any comparable type. This is the main entry point
- * for binary search operations.
+ * Searches for the given key in a sorted array.
*
- *
Example Usage:
- *
- * Integer[] numbers = {1, 3, 5, 7, 9, 11};
- * int result = new BinarySearch().find(numbers, 7);
- * // result will be 3 (index of element 7)
- *
- * int notFound = new BinarySearch().find(numbers, 4);
- * // notFound will be -1 (element 4 does not exist)
- *
- *
- * @param The type of elements in the array (must be Comparable)
- * @param array The sorted array to search in (MUST be sorted in ascending order)
- * @param key The element to search for
- * @return The index of the key if found, -1 if not found or if array is null/empty
+ * @param the type of elements in the array; must implement {@link Comparable}
+ * @param array the sorted array to search in
+ * @param key the element to search for
+ * @return the index of the key if found, or {@code -1} if the key is not found
*/
@Override
public > int find(T[] array, T key) {
- // Handle edge case: empty array
- if (array == null || array.length == 0) {
- return -1;
- }
- // Delegate to the core search implementation
return search(array, key, 0, array.length - 1);
}
/**
- * Core recursive implementation of binary search algorithm. This method divides the problem
- * into smaller subproblems recursively.
- *
- * How it works:
- *
- * - Calculate the middle index to avoid integer overflow
- * - Check if middle element matches the target
- * - If not, recursively search either left or right half
- * - Base case: left > right means element not found
- *
+ * Recursively searches for the key between the given left and right indexes.
*
- * Time Complexity: O(log n) because we halve the search space each time.
- * Space Complexity: O(log n) due to recursive call stack.
- *
- * @param The type of elements (must be Comparable)
- * @param array The sorted array to search in
- * @param key The element we're looking for
- * @param left The leftmost index of current search range (inclusive)
- * @param right The rightmost index of current search range (inclusive)
- * @return The index where key is located, or -1 if not found
+ * @param the type of elements in the array; must implement {@link Comparable}
+ * @param array the sorted array to search in
+ * @param key the element to search for
+ * @param left the left boundary of the current search range
+ * @param right the right boundary of the current search range
+ * @return the index of the key if found, or {@code -1} if the key is not found
*/
private > int search(T[] array, T key, int left, int right) {
- // Base case: Search space is exhausted
- // This happens when left pointer crosses right pointer
if (right < left) {
- return -1; // Key not found in the array
+ return -1;
}
- // Calculate middle index
- // Using (left + right) / 2 could cause integer overflow for large arrays
- // So we use: left + (right - left) / 2 which is mathematically equivalent
- // but prevents overflow
- int median = (left + right) >>> 1; // Unsigned right shift is faster division by 2
-
- // Get the value at middle position for comparison
+ int median = (left + right) >>> 1;
int comp = key.compareTo(array[median]);
-
- // Case 1: Found the target element at middle position
if (comp == 0) {
- return median; // Return the index where element was found
+ return median;
}
- // Case 2: Target is smaller than middle element
- // This means if target exists, it must be in the LEFT half
else if (comp < 0) {
- // Recursively search the left half
- // New search range: [left, median - 1]
return search(array, key, left, median - 1);
}
- // Case 3: Target is greater than middle element
- // This means if target exists, it must be in the RIGHT half
else {
- // Recursively search the right half
- // New search range: [median + 1, right]
return search(array, key, median + 1, right);
}
}