Skip to content

Commit 233a78c

Browse files
Fix infinite loop in JumpSearch when key exceeds last element
1 parent ec0f2cd commit 233a78c

2 files changed

Lines changed: 49 additions & 1 deletion

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public <T extends Comparable<T>> int find(T[] array, T key) {
7373
int limit = blockSize;
7474
// Jumping ahead to find the block where the key may be located
7575
while (limit < length && key.compareTo(array[limit]) > 0) {
76-
limit = Math.min(limit + blockSize, length - 1);
76+
limit += blockSize;
7777
}
7878

7979
// Perform linear search within the identified block

src/test/java/com/thealgorithms/searches/JumpSearchTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44

5+
import java.util.concurrent.TimeUnit;
56
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.Timeout;
68

79
/**
810
* Unit tests for the JumpSearch class.
@@ -91,4 +93,50 @@ void testJumpSearchLargeArrayNotFound() {
9193
Integer key = 999; // Key not present
9294
assertEquals(-1, jumpSearch.find(array, key), "The element should not be found in the array.");
9395
}
96+
97+
/**
98+
* A key greater than every element used to make the jumping loop spin forever, because the
99+
* cursor was clamped to the last index and therefore stopped advancing.
100+
*/
101+
@Test
102+
@Timeout(value = 5, unit = TimeUnit.SECONDS, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
103+
void testJumpSearchKeyGreaterThanLastElement() {
104+
JumpSearch jumpSearch = new JumpSearch();
105+
Integer[] array = {1, 2, 3, 4};
106+
assertEquals(-1, jumpSearch.find(array, 5), "A key above the maximum should not be found.");
107+
}
108+
109+
/**
110+
* The same regression across several lengths, since the jump size depends on the array length.
111+
*/
112+
@Test
113+
@Timeout(value = 5, unit = TimeUnit.SECONDS, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
114+
void testJumpSearchKeyGreaterThanLastElementForEveryLength() {
115+
JumpSearch jumpSearch = new JumpSearch();
116+
for (int length = 1; length <= 50; length++) {
117+
Integer[] array = new Integer[length];
118+
for (int i = 0; i < length; i++) {
119+
array[i] = i;
120+
}
121+
assertEquals(-1, jumpSearch.find(array, length), "A key above the maximum should not be found for length " + length + ".");
122+
}
123+
}
124+
125+
/**
126+
* Every element must be found regardless of the array length, including the ones that sit
127+
* exactly on a jump boundary.
128+
*/
129+
@Test
130+
void testJumpSearchFindsEveryElement() {
131+
JumpSearch jumpSearch = new JumpSearch();
132+
for (int length = 1; length <= 50; length++) {
133+
Integer[] array = new Integer[length];
134+
for (int i = 0; i < length; i++) {
135+
array[i] = i * 2;
136+
}
137+
for (int i = 0; i < length; i++) {
138+
assertEquals(i, jumpSearch.find(array, i * 2), "Element at index " + i + " should be found for length " + length + ".");
139+
}
140+
}
141+
}
94142
}

0 commit comments

Comments
 (0)