From fafce27768fdb789fe82c3698d1078d865fd55b0 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Mon, 16 Apr 2018 19:30:29 +0300 Subject: [PATCH] Add binary search. --- README.md | 2 ++ src/algorithms/search/binary-search/README.md | 17 +++++++++ .../__test__/binarySearch.test.js | 34 ++++++++++++++++++ .../search/binary-search/binarySearch.js | 35 +++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 src/algorithms/search/binary-search/README.md create mode 100644 src/algorithms/search/binary-search/__test__/binarySearch.test.js create mode 100644 src/algorithms/search/binary-search/binarySearch.js diff --git a/README.md b/README.md index 5873a212..e8a8bcc8 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/src/algorithms/search/binary-search/README.md b/src/algorithms/search/binary-search/README.md new file mode 100644 index 00000000..0b55e1aa --- /dev/null +++ b/src/algorithms/search/binary-search/README.md @@ -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) diff --git a/src/algorithms/search/binary-search/__test__/binarySearch.test.js b/src/algorithms/search/binary-search/__test__/binarySearch.test.js new file mode 100644 index 00000000..72c2b344 --- /dev/null +++ b/src/algorithms/search/binary-search/__test__/binarySearch.test.js @@ -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); + }); +}); diff --git a/src/algorithms/search/binary-search/binarySearch.js b/src/algorithms/search/binary-search/binarySearch.js new file mode 100644 index 00000000..cc85b1ff --- /dev/null +++ b/src/algorithms/search/binary-search/binarySearch.js @@ -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; +}