Skip to content

Algorithm: Binary Search #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions Search/BinarySearch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @function binarySearch
* @description binary search algorithm (iterative & recursive implementations) for a sorted array.
*
* The algorithm searches for a specific value in a sorted array in logarithmic time.
* It repeatedly halves the portion of the list that could contain the item,
* until you've narrowed down the possible indices to just one.
*
* @param {number[]} array - sorted list of numbers
* @param {number} target - target number to search for
* @return {number} - index of the target number in the list, or -1 if not found
* @see [BinarySearch](https://www.geeksforgeeks.org/binary-search/)
* @example binarySearch([1,2,3], 2) => 1
* @example binarySearch([4,5,6], 2) => -1
*/

export const binarySearchIterative = (array: number[], target: number): number => {
if (array.length === 0) return -1;

// declare pointers for the start, middle and end indices
let start = 0,
end = array.length - 1,
middle = (start + end) >> 1;

// ensure the target is within the bounds of the array
if (target < array[start] || target > array[end]) return -1;

while (array[middle] !== target && start <= end) {
// if the target is less than the middle value, move the end pointer to be middle -1 to narrow the search space
// otherwise, move the start pointer to be middle + 1
if (target < array[middle])
end = middle - 1;
else
start = middle + 1;
// redeclare the middle index when the search window changes
middle = (start + end) >> 1;
}
// return the middle index if it is equal to target
return array[middle] === target ? middle : -1;
}

export const binarySearchRecursive = (array: number[], target: number, start = 0, end = array.length - 1): number => {
if (array.length === 0) return -1;

// ensure the target is within the bounds of the array
if (target < array[start] || target > array[end]) return -1;

const middle = (start + end) >> 1;

if (array[middle] === target) return middle; // target found
if (start > end) return -1; // target not found

// if the target is less than the middle value, move the end pointer to be middle -1 to narrow the search space
// otherwise, move the start pointer to be middle + 1
return target < array[middle]
? binarySearchRecursive(array, target, start, middle - 1)
: binarySearchRecursive(array, target, middle + 1, end);
}
34 changes: 34 additions & 0 deletions Search/test/BinarySearch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { binarySearchIterative, binarySearchRecursive } from "../BinarySearch";

describe("BinarySearch", () => {
const testArray: number[] = [1,2,3,4];
type FunctionsArray = { (array: number[], index: number): number }[];
const functions: FunctionsArray = [binarySearchIterative, binarySearchRecursive];

for (const func of functions) {
it("should be defined", () => {
expect(func(testArray, 2)).toBeDefined();
});
it("should return a number", () => {
expect(typeof func(testArray, 2)).toBe("number");
});
it("should return -1 if the target is not found in the array", () => {
expect(func(testArray, 5)).toBe(-1);
});
it("should return -1 if there are no elements in the array", () => {
expect(func([], 5)).toBe(-1);
});
it("should return the index of the target if it is found in the array", () => {
expect(func(testArray, 2)).toBe(1);
});
it("should return a correct index of target when the array contains duplicate values", () => {
expect(func([1,2,2,3,3,3,4], 2)).toBe(1);
});
it("should return the first index when the target is the first item in the array", () => {
expect(func(testArray, 1)).toBe(0);
});
it("should return the last index when the target is the last item in the array", () => {
expect(func(testArray, 4)).toBe(3);
});
}
});