Add Jump Search algorithm.

This commit is contained in:
Oleksii Trekhleb 2018-07-18 09:21:20 +03:00
parent b73ddec94d
commit a327b68a06
8 changed files with 114 additions and 0 deletions

View File

@ -84,6 +84,7 @@ a set of rules that precisely define a sequence of operations.
* `A` [Regular Expression Matching](src/algorithms/string/regular-expression-matching)
* **Searches**
* `B` [Linear Search](src/algorithms/search/linear-search)
* `B` [Jump Search](src/algorithms/search/jump-search)
* `B` [Binary Search](src/algorithms/search/binary-search)
* **Sorting**
* `B` [Bubble Sort](src/algorithms/sorting/bubble-sort)
@ -129,6 +130,7 @@ of algorithms. It is an abstraction higher than the notion of an algorithm, just
algorithm is an abstraction higher than a computer program.
* **Brute Force** - look at all the possibilities and selects the best solution
* `B` [Linear Search](src/algorithms/search/linear-search)
* `A` [Maximum Subarray](src/algorithms/sets/maximum-subarray)
* `A` [Travelling Salesman Problem](src/algorithms/graph/travelling-salesman) - shortest possible route that visits each city and returns to the origin city
* **Greedy** - choose the best option at the current time, without any consideration for the future

View File

@ -12,6 +12,11 @@ in the array.
![Binary Search](https://upload.wikimedia.org/wikipedia/commons/8/83/Binary_Search_Depiction.svg)
## Complexity
**Time Complexity**: `O(log(n))` - since we split search area by two for every
next iteration.
## References
- [Wikipedia](https://en.wikipedia.org/wiki/Binary_search_algorithm)

View File

@ -1,6 +1,8 @@
import Comparator from '../../../utils/comparator/Comparator';
/**
* Binary search implementation.
*
* @param {*[]} sortedArray
* @param {*} seekElement
* @param {function(a, b)} [comparatorCallback]

View File

@ -0,0 +1,27 @@
# Jump Search
Like Binary Search, **Jump Search** (or **Block Search**) is a searching algorithm
for sorted arrays. The basic idea is to check fewer elements (than linear search)
by jumping ahead by fixed steps or skipping some elements in place of searching all
elements.
For example, suppose we have an array `arr[]` of size `n` and block (to be jumped)
of size `m`. Then we search at the indexes `arr[0]`, `arr[m]`, `arr[2 * m]`, ..., `arr[k * m]` and
so on. Once we find the interval `arr[k * m] < x < arr[(k+1) * m]`, we perform a
linear search operation from the index `k * m` to find the element `x`.
**What is the optimal block size to be skipped?**
In the worst case, we have to do `n/m` jumps and if the last checked value is
greater than the element to be searched for, we perform `m - 1` comparisons more
for linear search. Therefore the total number of comparisons in the worst case
will be `((n/m) + m - 1)`. The value of the function `((n/m) + m - 1)` will be
minimum when `m = √n`. Therefore, the best step size is `m = √n`.
## Complexity
**Time complexity**: `O(√n)` - because we do search by blocks of size `√n`.
## References
- [Wikipedia](https://en.wikipedia.org/wiki/Jump_search)
- [GeeksForGeeks](https://www.geeksforgeeks.org/jump-search/)

View File

@ -0,0 +1,20 @@
import jumpSearch from '../jumpSearch';
describe('jumpSearch', () => {
it('should search for an element in sorted array', () => {
expect(jumpSearch([], 1)).toBe(-1);
expect(jumpSearch([1], 2)).toBe(-1);
expect(jumpSearch([1], 1)).toBe(0);
expect(jumpSearch([1, 2], 1)).toBe(0);
expect(jumpSearch([1, 2], 1)).toBe(0);
expect(jumpSearch([1, 1, 1], 1)).toBe(0);
expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 2)).toBe(1);
expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 0)).toBe(-1);
expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 0)).toBe(-1);
expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 7)).toBe(-1);
expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 5)).toBe(2);
expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 20)).toBe(4);
expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 30)).toBe(7);
expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 48)).toBe(8);
});
});

View File

@ -0,0 +1,51 @@
import Comparator from '../../../utils/comparator/Comparator';
/**
* Jump (block) search implementation.
*
* @param {*[]} sortedArray.
* @param {*} seekElement
* @param {function(a, b)} [comparatorCallback]
* @return {number}
*/
export default function jumpSearch(sortedArray, seekElement, comparatorCallback) {
const comparator = new Comparator(comparatorCallback);
const arraySize = sortedArray.length;
if (!arraySize) {
// We can't find anything in empty array.
return -1;
}
// Calculate optimal jump size.
// Total number of comparisons in the worst case will be ((arraySize/jumpSize) + jumpSize - 1).
// The value of the function ((arraySize/jumpSize) + jumpSize - 1) will be minimum
// when jumpSize = √array.length.
const jumpSize = Math.floor(Math.sqrt(arraySize));
// Find the block where the seekElement belong to.
let blockStart = 0;
let blockEnd = jumpSize;
while (comparator.greaterThan(seekElement, sortedArray[Math.min(blockEnd, arraySize) - 1])) {
// Jump to the next block.
blockStart = blockEnd;
blockEnd += jumpSize;
// If our next block is out of array then we couldn't found the element.
if (blockStart > arraySize) {
return -1;
}
}
// Do linear search for seekElement in subarray starting from blockStart.
let currentIndex = blockStart;
while (currentIndex < Math.min(blockEnd, arraySize)) {
if (comparator.equal(sortedArray[currentIndex], seekElement)) {
return currentIndex;
}
currentIndex += 1;
}
return -1;
}

View File

@ -8,6 +8,11 @@ comparisons, where `n` is the length of the list.
![Linear Search](https://www.tutorialspoint.com/data_structures_algorithms/images/linear_search.gif)
## Complexity
**Time Complexity**: `O(n)` - since in worst case we're checking each element
exactly once.
## References
- [Wikipedia](https://en.wikipedia.org/wiki/Linear_search)
- [TutorialsPoint](https://www.tutorialspoint.com/data_structures_algorithms/linear_search_algorithm.htm)

View File

@ -1,6 +1,8 @@
import Comparator from '../../../utils/comparator/Comparator';
/**
* Linear search implementation.
*
* @param {*[]} array
* @param {*} seekElement
* @param {function(a, b)} [comparatorCallback]