diff --git a/src/main/java/com/thealgorithms/searches/JumpSearch.java b/src/main/java/com/thealgorithms/searches/JumpSearch.java index 5074aa7845c8..4253f4182db1 100644 --- a/src/main/java/com/thealgorithms/searches/JumpSearch.java +++ b/src/main/java/com/thealgorithms/searches/JumpSearch.java @@ -73,7 +73,7 @@ public > int find(T[] array, T key) { int limit = blockSize; // Jumping ahead to find the block where the key may be located while (limit < length && key.compareTo(array[limit]) > 0) { - limit = Math.min(limit + blockSize, length - 1); + limit += blockSize; } // Perform linear search within the identified block diff --git a/src/test/java/com/thealgorithms/searches/JumpSearchTest.java b/src/test/java/com/thealgorithms/searches/JumpSearchTest.java index 3fa319b66a41..a5ce93b8a3af 100644 --- a/src/test/java/com/thealgorithms/searches/JumpSearchTest.java +++ b/src/test/java/com/thealgorithms/searches/JumpSearchTest.java @@ -2,7 +2,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; /** * Unit tests for the JumpSearch class. @@ -91,4 +93,50 @@ void testJumpSearchLargeArrayNotFound() { Integer key = 999; // Key not present assertEquals(-1, jumpSearch.find(array, key), "The element should not be found in the array."); } + + /** + * A key greater than every element used to make the jumping loop spin forever, because the + * cursor was clamped to the last index and therefore stopped advancing. + */ + @Test + @Timeout(value = 5, unit = TimeUnit.SECONDS, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + void testJumpSearchKeyGreaterThanLastElement() { + JumpSearch jumpSearch = new JumpSearch(); + Integer[] array = {1, 2, 3, 4}; + assertEquals(-1, jumpSearch.find(array, 5), "A key above the maximum should not be found."); + } + + /** + * The same regression across several lengths, since the jump size depends on the array length. + */ + @Test + @Timeout(value = 5, unit = TimeUnit.SECONDS, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + void testJumpSearchKeyGreaterThanLastElementForEveryLength() { + JumpSearch jumpSearch = new JumpSearch(); + for (int length = 1; length <= 50; length++) { + Integer[] array = new Integer[length]; + for (int i = 0; i < length; i++) { + array[i] = i; + } + assertEquals(-1, jumpSearch.find(array, length), "A key above the maximum should not be found for length " + length + "."); + } + } + + /** + * Every element must be found regardless of the array length, including the ones that sit + * exactly on a jump boundary. + */ + @Test + void testJumpSearchFindsEveryElement() { + JumpSearch jumpSearch = new JumpSearch(); + for (int length = 1; length <= 50; length++) { + Integer[] array = new Integer[length]; + for (int i = 0; i < length; i++) { + array[i] = i * 2; + } + for (int i = 0; i < length; i++) { + assertEquals(i, jumpSearch.find(array, i * 2), "Element at index " + i + " should be found for length " + length + "."); + } + } + } }