diff --git a/src/algorithms/search/interpolation-search/__test__/interpolationSearch.test.js b/src/algorithms/search/interpolation-search/__test__/interpolationSearch.test.js index 7ddc548b63..21d7576c7d 100644 --- a/src/algorithms/search/interpolation-search/__test__/interpolationSearch.test.js +++ b/src/algorithms/search/interpolation-search/__test__/interpolationSearch.test.js @@ -21,4 +21,11 @@ describe('interpolationSearch', () => { expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 19000], 800)).toBe(4); expect(interpolationSearch([0, 10, 11, 12, 13, 14, 15], 10)).toBe(1); }); + + it('should not loop forever when the seek element is above part of the range', () => { + // Regression test: without the fix this call hangs forever. + expect(interpolationSearch([2, 4, 8, 8, 10, 12, 18, 20, 20, 20, 22, 26, 26, 28], 24)).toBe(-1); + expect(interpolationSearch([1, 2, 4, 8, 16, 32, 64, 128], 48)).toBe(-1); + expect(interpolationSearch([1, 3, 5, 7, 9], 8)).toBe(-1); + }); }); diff --git a/src/algorithms/search/interpolation-search/interpolationSearch.js b/src/algorithms/search/interpolation-search/interpolationSearch.js index 8546c5be3b..11a51badea 100644 --- a/src/algorithms/search/interpolation-search/interpolationSearch.js +++ b/src/algorithms/search/interpolation-search/interpolationSearch.js @@ -21,6 +21,14 @@ export default function interpolationSearch(sortedArray, seekElement) { return -1; } + // If the seek element is higher than the highest element from the range + // then there is no seek element exists in array. This check also guarantees + // that valueDelta is not greater than rangeDelta, so the interpolated + // middleIndex always stays inside of [leftIndex, rightIndex] range. + if (seekElement > sortedArray[rightIndex]) { + return -1; + } + // If range delta is zero then subarray contains all the same numbers // and thus there is nothing to search for unless this range is all // consists of seek number.