diff --git a/DIRECTORY.md b/DIRECTORY.md index ce0e7c51..166aea22 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -110,6 +110,7 @@ ## Search * [Binary Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/binary_search.ts) + * [Interpolation Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/interpolation_search.ts) * [Jump Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/jump_search.ts) * [Linear Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/linear_search.ts) diff --git a/search/interpolation_search.ts b/search/interpolation_search.ts new file mode 100644 index 00000000..61942782 --- /dev/null +++ b/search/interpolation_search.ts @@ -0,0 +1,49 @@ +/** + * @function interpolationSearch + * @description Interpolation search is an algorithm for searching for a + * key in an array that has been ordered by numerical values assigned + * to the keys (key values) + * @param {number[]} array - list of numbers + * @param {number} target - target number to search for + * @return {number} - index of the target number in the list, or -1 if not found + * @see https://en.wikipedia.org/wiki/Interpolation_search + * @example interpolationSearch([1, 3, 5, 7, 9, 11], 1) => 0 + */ +export const interpolationSearch = (array: number[], target: number): number => { + let lowIndex: number = 0; + let highIndex: number = array.length - 1; + let currentValue: number = array[lowIndex]; + let pos: number = 0; + + while (lowIndex <= highIndex) { + const lowValue: number = array[lowIndex]; + const highValue: number = array[highIndex]; + + if (lowValue === highValue) { + if (array[lowIndex] === target) { + return lowIndex; + } + break; + } + + pos = Math.round(lowIndex + (target-lowValue)*(highIndex-lowIndex) / (highValue-lowValue)); + + if (pos < 0 || pos >= array.length) { + break; + } + + currentValue = array[pos]; + + if (target === currentValue) { + return pos; + } + + if (target > currentValue) { + lowIndex = pos + 1; + } else { + highIndex = pos - 1; + } + } + + return -1; +} \ No newline at end of file diff --git a/search/test/interpolation_search.test.ts b/search/test/interpolation_search.test.ts new file mode 100644 index 00000000..6cc6e4e2 --- /dev/null +++ b/search/test/interpolation_search.test.ts @@ -0,0 +1,15 @@ +import { interpolationSearch } from "../interpolation_search"; + +describe("Interpolation search", () => { + test.each([ + [[1, 3, 5, 7, 9, 11], 1, 0], + [[1, 3, 7, 10, 14, 15, 16, 18, 20, 21, 22, 23, 25, 33, 35, 42, 45, 47, 50, 52], 33, 13], + [[0, 45, 67, 70, 89, 129, 150, 308], 308, 7], + [[0, 45, 67, 70, 89, 129, 150, 308], 190, -1] + ])( + "of %o, searching for %o, expected %i", + (array: any[], target: any, index: number) => { + expect(interpolationSearch(array, target)).toStrictEqual(index) + }, + ); +});