Skip to content

Commit b8ce582

Browse files
authored
Add Binary Search (#32)
1 parent eb8261f commit b8ce582

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

Search/BinarySearch.ts

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* @function binarySearch
3+
* @description binary search algorithm (iterative & recursive implementations) for a sorted array.
4+
*
5+
* The algorithm searches for a specific value in a sorted array in logarithmic time.
6+
* It repeatedly halves the portion of the list that could contain the item,
7+
* until you've narrowed down the possible indices to just one.
8+
*
9+
* @param {number[]} array - sorted list of numbers
10+
* @param {number} target - target number to search for
11+
* @return {number} - index of the target number in the list, or -1 if not found
12+
* @see [BinarySearch](https://www.geeksforgeeks.org/binary-search/)
13+
* @example binarySearch([1,2,3], 2) => 1
14+
* @example binarySearch([4,5,6], 2) => -1
15+
*/
16+
17+
export const binarySearchIterative = (array: number[], target: number): number => {
18+
if (array.length === 0) return -1;
19+
20+
// declare pointers for the start, middle and end indices
21+
let start = 0,
22+
end = array.length - 1,
23+
middle = (start + end) >> 1;
24+
25+
// ensure the target is within the bounds of the array
26+
if (target < array[start] || target > array[end]) return -1;
27+
28+
while (array[middle] !== target && start <= end) {
29+
// if the target is less than the middle value, move the end pointer to be middle -1 to narrow the search space
30+
// otherwise, move the start pointer to be middle + 1
31+
if (target < array[middle])
32+
end = middle - 1;
33+
else
34+
start = middle + 1;
35+
// redeclare the middle index when the search window changes
36+
middle = (start + end) >> 1;
37+
}
38+
// return the middle index if it is equal to target
39+
return array[middle] === target ? middle : -1;
40+
}
41+
42+
export const binarySearchRecursive = (array: number[], target: number, start = 0, end = array.length - 1): number => {
43+
if (array.length === 0) return -1;
44+
45+
// ensure the target is within the bounds of the array
46+
if (target < array[start] || target > array[end]) return -1;
47+
48+
const middle = (start + end) >> 1;
49+
50+
if (array[middle] === target) return middle; // target found
51+
if (start > end) return -1; // target not found
52+
53+
// if the target is less than the middle value, move the end pointer to be middle -1 to narrow the search space
54+
// otherwise, move the start pointer to be middle + 1
55+
return target < array[middle]
56+
? binarySearchRecursive(array, target, start, middle - 1)
57+
: binarySearchRecursive(array, target, middle + 1, end);
58+
}

Search/test/BinarySearch.test.ts

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { binarySearchIterative, binarySearchRecursive } from "../BinarySearch";
2+
3+
describe("BinarySearch", () => {
4+
const testArray: number[] = [1,2,3,4];
5+
type FunctionsArray = { (array: number[], index: number): number }[];
6+
const functions: FunctionsArray = [binarySearchIterative, binarySearchRecursive];
7+
8+
for (const func of functions) {
9+
it("should be defined", () => {
10+
expect(func(testArray, 2)).toBeDefined();
11+
});
12+
it("should return a number", () => {
13+
expect(typeof func(testArray, 2)).toBe("number");
14+
});
15+
it("should return -1 if the target is not found in the array", () => {
16+
expect(func(testArray, 5)).toBe(-1);
17+
});
18+
it("should return -1 if there are no elements in the array", () => {
19+
expect(func([], 5)).toBe(-1);
20+
});
21+
it("should return the index of the target if it is found in the array", () => {
22+
expect(func(testArray, 2)).toBe(1);
23+
});
24+
it("should return a correct index of target when the array contains duplicate values", () => {
25+
expect(func([1,2,2,3,3,3,4], 2)).toBe(1);
26+
});
27+
it("should return the first index when the target is the first item in the array", () => {
28+
expect(func(testArray, 1)).toBe(0);
29+
});
30+
it("should return the last index when the target is the last item in the array", () => {
31+
expect(func(testArray, 4)).toBe(3);
32+
});
33+
}
34+
});

0 commit comments

Comments
 (0)