Skip to content

Commit 55f551b

Browse files
Fix ExponentialSearch missing boundary elements and not returning -1 (#7556)
Co-authored-by: Oleksandr Klymenko <alexanderklmn@gmail.com>
1 parent 171bdc5 commit 55f551b

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public <T extends Comparable<T>> int find(T[] array, T key) {
4646
range = range * 2;
4747
}
4848

49-
return Arrays.binarySearch(array, range / 2, Math.min(range, array.length), key);
49+
// The candidate block is the inclusive index range [range / 2, range], so the
50+
// exclusive upper bound handed to binarySearch has to be range + 1.
51+
final int index = Arrays.binarySearch(array, range / 2, Math.min(range + 1, array.length), key);
52+
return index >= 0 ? index : -1;
5053
}
5154
}

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,46 @@ void testExponentialSearchLargeArray() {
8181
int expectedIndex = 9999;
8282
assertEquals(expectedIndex, exponentialSearch.find(array, key), "The index of the last element should be 9999.");
8383
}
84+
85+
/**
86+
* An element sitting exactly on the doubling boundary used to be reported as missing, because
87+
* the binary search was handed {@code range} as its exclusive upper bound instead of
88+
* {@code range + 1}.
89+
*/
90+
@Test
91+
void testExponentialSearchElementOnRangeBoundary() {
92+
ExponentialSearch exponentialSearch = new ExponentialSearch();
93+
Integer[] array = {-25, -9, 8, 21};
94+
assertEquals(2, exponentialSearch.find(array, 8), "The index of the found element should be 2.");
95+
}
96+
97+
/**
98+
* Every element must be found regardless of the array length.
99+
*/
100+
@Test
101+
void testExponentialSearchFindsEveryElement() {
102+
ExponentialSearch exponentialSearch = new ExponentialSearch();
103+
for (int length = 1; length <= 50; length++) {
104+
Integer[] array = new Integer[length];
105+
for (int i = 0; i < length; i++) {
106+
array[i] = i * 2;
107+
}
108+
for (int i = 0; i < length; i++) {
109+
assertEquals(i, exponentialSearch.find(array, i * 2), "Element at index " + i + " should be found for length " + length + ".");
110+
}
111+
}
112+
}
113+
114+
/**
115+
* A missing key has to yield -1 rather than the negative insertion point that
116+
* {@link java.util.Arrays#binarySearch} returns.
117+
*/
118+
@Test
119+
void testExponentialSearchNotFoundReturnsMinusOne() {
120+
ExponentialSearch exponentialSearch = new ExponentialSearch();
121+
Integer[] array = {1, 3, 5, 7, 9, 11};
122+
assertEquals(-1, exponentialSearch.find(array, 4), "A key inside the range but absent should give -1.");
123+
assertEquals(-1, exponentialSearch.find(array, 0), "A key below the minimum should give -1.");
124+
assertEquals(-1, exponentialSearch.find(array, 12), "A key above the maximum should give -1.");
125+
}
84126
}

0 commit comments

Comments
 (0)