Add binary search.

This commit is contained in:
Oleksii Trekhleb 2018-04-16 19:30:29 +03:00
parent c7110be47e
commit fafce27768
4 changed files with 88 additions and 0 deletions

View File

@ -30,6 +30,8 @@
* Graph
* [Depth-First Search (DFS)](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/graph/depth-first-search)
* [Breadth-First Search (BFS)](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/graph/breadth-first-search)
* Search
* [Binary Search](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/search/binary-search)
* Sorting
* [Bubble Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/bubble-sort)
* [Selection Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/selection-sort)

View File

@ -0,0 +1,17 @@
# Binary Search
In computer science, binary search, also known as half-interval
search, logarithmic search, or binary chop, is a search algorithm
that finds the position of a target value within a sorted
array. Binary search compares the target value to the middle
element of the array; if they are unequal, the half in which
the target cannot lie is eliminated and the search continues
on the remaining half until it is successful. If the search
ends with the remaining half being empty, the target is not
in the array.
![Binary Search](https://upload.wikimedia.org/wikipedia/commons/8/83/Binary_Search_Depiction.svg)
## References
[Wikipedia](https://en.wikipedia.org/wiki/Binary_search_algorithm)

View File

@ -0,0 +1,34 @@
import binarySearch from '../binarySearch';
describe('binarySearch', () => {
it('should search number in sorted array', () => {
expect(binarySearch([], 1)).toBe(-1);
expect(binarySearch([1], 1)).toBe(0);
expect(binarySearch([1, 2], 1)).toBe(0);
expect(binarySearch([1, 2], 2)).toBe(1);
expect(binarySearch([1, 5, 10, 12], 1)).toBe(0);
expect(binarySearch([1, 5, 10, 12, 14, 17, 22, 100], 17)).toBe(5);
expect(binarySearch([1, 5, 10, 12, 14, 17, 22, 100], 1)).toBe(0);
expect(binarySearch([1, 5, 10, 12, 14, 17, 22, 100], 100)).toBe(7);
expect(binarySearch([1, 5, 10, 12, 14, 17, 22, 100], 0)).toBe(-1);
});
it('should search object in sorted array', () => {
const sortedArrayOfObjects = [
{ key: 1, value: 'value1' },
{ key: 2, value: 'value2' },
{ key: 3, value: 'value3' },
];
const comparator = (a, b) => {
if (a.key === b.key) return 0;
return a.key < b.key ? -1 : 1;
};
expect(binarySearch([], { key: 1 }, comparator)).toBe(-1);
expect(binarySearch(sortedArrayOfObjects, { key: 4 }, comparator)).toBe(-1);
expect(binarySearch(sortedArrayOfObjects, { key: 1 }, comparator)).toBe(0);
expect(binarySearch(sortedArrayOfObjects, { key: 2 }, comparator)).toBe(1);
expect(binarySearch(sortedArrayOfObjects, { key: 3 }, comparator)).toBe(2);
});
});

View File

@ -0,0 +1,35 @@
import Comparator from '../../../utils/comparator/Comparator';
/**
* @param {*[]} sortedArray
* @param {*} seekElement
* @param {function(a, b)} [comparatorCallback]
* @return {number}
*/
export default function binarySearch(sortedArray, seekElement, comparatorCallback) {
const comparator = new Comparator(comparatorCallback);
let startIndex = 0;
let endIndex = sortedArray.length - 1;
while (startIndex <= endIndex) {
const middleIndex = startIndex + Math.floor((endIndex - startIndex) / 2);
// If we've found the element just return its position.
if (comparator.equal(sortedArray[middleIndex], seekElement)) {
return middleIndex;
}
// Decide which half to choose for seeking next: left or right one.
if (comparator.lessThen(sortedArray[middleIndex], seekElement)) {
// Go to the right half of the array.
startIndex = middleIndex + 1;
} else {
// Go to the left half of the array.
endIndex = middleIndex - 1;
}
}
return -1;
}