mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-07-07 18:10:24 +08:00
Add Interpolation Search.
This commit is contained in:
@ -86,6 +86,7 @@ a set of rules that precisely define a sequence of operations.
|
|||||||
* `B` [Linear Search](src/algorithms/search/linear-search)
|
* `B` [Linear Search](src/algorithms/search/linear-search)
|
||||||
* `B` [Jump Search](src/algorithms/search/jump-search) (or Block Search) - search in sorted array
|
* `B` [Jump Search](src/algorithms/search/jump-search) (or Block Search) - search in sorted array
|
||||||
* `B` [Binary Search](src/algorithms/search/binary-search) - search in sorted array
|
* `B` [Binary Search](src/algorithms/search/binary-search) - search in sorted array
|
||||||
|
* `B` [Interpolation Search](src/algorithms/search/interpolation-search) - search in uniformly distributed sorted array
|
||||||
* **Sorting**
|
* **Sorting**
|
||||||
* `B` [Bubble Sort](src/algorithms/sorting/bubble-sort)
|
* `B` [Bubble Sort](src/algorithms/sorting/bubble-sort)
|
||||||
* `B` [Selection Sort](src/algorithms/sorting/selection-sort)
|
* `B` [Selection Sort](src/algorithms/sorting/selection-sort)
|
||||||
|
40
src/algorithms/search/interpolation-search/README.md
Normal file
40
src/algorithms/search/interpolation-search/README.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Interpolation Search
|
||||||
|
|
||||||
|
**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).
|
||||||
|
|
||||||
|
For example we have a sorted array of `n` uniformly distributed values `arr[]`,
|
||||||
|
and we need to write a function to search for a particular element `x` in the array.
|
||||||
|
|
||||||
|
**Linear Search** finds the element in `O(n)` time, **Jump Search** takes `O(√ n)` time
|
||||||
|
and **Binary Search** take `O(Log n)` time.
|
||||||
|
|
||||||
|
The **Interpolation Search** is an improvement over Binary Search for instances,
|
||||||
|
where the values in a sorted array are _uniformly_ distributed. Binary Search
|
||||||
|
always goes to the middle element to check. On the other hand, interpolation
|
||||||
|
search may go to different locations according to the value of the key being
|
||||||
|
searched. For example, if the value of the key is closer to the last element,
|
||||||
|
interpolation search is likely to start search toward the end side.
|
||||||
|
|
||||||
|
To find the position to be searched, it uses following formula:
|
||||||
|
|
||||||
|
```
|
||||||
|
// The idea of formula is to return higher value of pos
|
||||||
|
// when element to be searched is closer to arr[hi]. And
|
||||||
|
// smaller value when closer to arr[lo]
|
||||||
|
pos = lo + ((x - arr[lo]) * (hi - lo) / (arr[hi] - arr[Lo]))
|
||||||
|
|
||||||
|
arr[] - Array where elements need to be searched
|
||||||
|
x - Element to be searched
|
||||||
|
lo - Starting index in arr[]
|
||||||
|
hi - Ending index in arr[]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
**Time complexity**: `O(log(log(n))`
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [GeeksForGeeks](https://www.geeksforgeeks.org/interpolation-search/)
|
||||||
|
- [Wikipedia](https://en.wikipedia.org/wiki/Interpolation_search)
|
@ -0,0 +1,24 @@
|
|||||||
|
import interpolationSearch from '../interpolationSearch';
|
||||||
|
|
||||||
|
describe('interpolationSearch', () => {
|
||||||
|
it('should search elements in sorted array of numbers', () => {
|
||||||
|
expect(interpolationSearch([], 1)).toBe(-1);
|
||||||
|
expect(interpolationSearch([1], 1)).toBe(0);
|
||||||
|
expect(interpolationSearch([1], 0)).toBe(-1);
|
||||||
|
expect(interpolationSearch([1, 1], 1)).toBe(0);
|
||||||
|
expect(interpolationSearch([1, 2], 1)).toBe(0);
|
||||||
|
expect(interpolationSearch([1, 2], 2)).toBe(1);
|
||||||
|
expect(interpolationSearch([10, 20, 30, 40, 50], 40)).toBe(3);
|
||||||
|
expect(interpolationSearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 14)).toBe(13);
|
||||||
|
expect(interpolationSearch([1, 6, 7, 8, 12, 13, 14, 19, 21, 23, 24, 24, 24, 300], 24)).toBe(10);
|
||||||
|
expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 600)).toBe(-1);
|
||||||
|
expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 1)).toBe(0);
|
||||||
|
expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 2)).toBe(1);
|
||||||
|
expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 3)).toBe(2);
|
||||||
|
expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 700)).toBe(3);
|
||||||
|
expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 800)).toBe(4);
|
||||||
|
expect(interpolationSearch([0, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 1200)).toBe(5);
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* Interpolation search implementation.
|
||||||
|
*
|
||||||
|
* @param {*[]} sortedArray - sorted array with uniformly distributed values
|
||||||
|
* @param {*} seekElement
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
export default function interpolationSearch(sortedArray, seekElement) {
|
||||||
|
let leftIndex = 0;
|
||||||
|
let rightIndex = sortedArray.length - 1;
|
||||||
|
|
||||||
|
while (leftIndex <= rightIndex) {
|
||||||
|
const rangeDelta = sortedArray[rightIndex] - sortedArray[leftIndex];
|
||||||
|
const indexDelta = rightIndex - leftIndex;
|
||||||
|
const valueDelta = seekElement - sortedArray[leftIndex];
|
||||||
|
|
||||||
|
// If valueDelta is less then zero it means that there is no seek element
|
||||||
|
// exists in array since the lowest element from the range is already higher
|
||||||
|
// then seek element.
|
||||||
|
if (valueDelta < 0) {
|
||||||
|
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.
|
||||||
|
if (!rangeDelta) {
|
||||||
|
// By doing this we're also avoiding division by zero while
|
||||||
|
// calculating the middleIndex later.
|
||||||
|
return sortedArray[leftIndex] === seekElement ? leftIndex : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do interpolation of the middle index.
|
||||||
|
const middleIndex = leftIndex + Math.floor(valueDelta * indexDelta / rangeDelta);
|
||||||
|
|
||||||
|
// If we've found the element just return its position.
|
||||||
|
if (sortedArray[middleIndex] === seekElement) {
|
||||||
|
return middleIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decide which half to choose for seeking next: left or right one.
|
||||||
|
if (sortedArray[middleIndex] < seekElement) {
|
||||||
|
// Go to the right half of the array.
|
||||||
|
leftIndex = middleIndex + 1;
|
||||||
|
} else {
|
||||||
|
// Go to the left half of the array.
|
||||||
|
rightIndex = middleIndex - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
@ -23,5 +23,5 @@ minimum when `m = √n`. Therefore, the best step size is `m = √n`.
|
|||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [Wikipedia](https://en.wikipedia.org/wiki/Jump_search)
|
|
||||||
- [GeeksForGeeks](https://www.geeksforgeeks.org/jump-search/)
|
- [GeeksForGeeks](https://www.geeksforgeeks.org/jump-search/)
|
||||||
|
- [Wikipedia](https://en.wikipedia.org/wiki/Jump_search)
|
||||||
|
@ -3,7 +3,7 @@ import Comparator from '../../../utils/comparator/Comparator';
|
|||||||
/**
|
/**
|
||||||
* Jump (block) search implementation.
|
* Jump (block) search implementation.
|
||||||
*
|
*
|
||||||
* @param {*[]} sortedArray.
|
* @param {*[]} sortedArray
|
||||||
* @param {*} seekElement
|
* @param {*} seekElement
|
||||||
* @param {function(a, b)} [comparatorCallback]
|
* @param {function(a, b)} [comparatorCallback]
|
||||||
* @return {number}
|
* @return {number}
|
||||||
|
Reference in New Issue
Block a user