Algorithms

Find a value in a sorted list by halving the search range at every step — O(log n).

Version 1.1.0 Versions: 1.5.0 1.4.0 1.3.0 1.2.0 1.1.0 1.0.0

This is an older version. The current version is 1.5.0.

Implementations

Sign in to open in IDE Sign in with your Zerethon account to create your own copy of this sample.

Files

README.md
# Binary Search

Zerethon Official Sample `binary-search`, version 1.1.0, Node.js 22.

- `binary_search.js` — the algorithm (`binarySearch`, and `binarySearchSteps` to trace it)
- `main.js` — entry file: searches a few values and prints the steps
- `test_binary_search.js` — checks; set it as the entry file to run them

This project is your own copy. Changing it never changes the official sample.
See the algorithm animated: https://tools.zerethon.com/binary-search-visualizer
binary_search.js
// Binary search over a sorted array (Zerethon Official Sample: binary-search 1.1.0).

/** Return the index of target in a (sorted ascending), or -1 if it is absent. */
function binarySearch(a, target) {
    let lo = 0;
    let hi = a.length - 1;
    while (lo <= hi) {
        const mid = (lo + hi) >> 1;
        if (a[mid] === target) return mid;
        if (a[mid] < target) lo = mid + 1;
        else hi = mid - 1;
    }
    return -1;
}

/** Every comparison binarySearch makes, as [lo, mid, hi]. */
function binarySearchSteps(a, target) {
    const steps = [];
    let lo = 0;
    let hi = a.length - 1;
    while (lo <= hi) {
        const mid = (lo + hi) >> 1;
        steps.push([lo, mid, hi]);
        if (a[mid] === target) break;
        if (a[mid] < target) lo = mid + 1;
        else hi = mid - 1;
    }
    return steps;
}

module.exports = { binarySearch, binarySearchSteps };
main.js entry
const { binarySearch, binarySearchSteps } = require('./binary_search');

const numbers = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91];
console.log(`Sorted list: [${numbers.join(', ')}]`);
console.log();

for (const target of [23, 2, 91, 7]) {
    const index = binarySearch(numbers, target);
    const result = index !== -1 ? `found at index ${index}` : 'not found';
    console.log(`search ${String(target).padStart(2)}: ${result}`);
}

console.log();
console.log('Steps for 23 (lo, mid, hi):');
for (const [lo, mid, hi] of binarySearchSteps(numbers, 23)) {
    console.log(`  lo=${lo} mid=${mid} hi=${hi} -> a[mid]=${numbers[mid]}`);
}
test_binary_search.js
// Checks for binarySearch. To run them, set this file as the entry file
// (the ▶ button next to it in Files) and press Run.
const assert = require('assert');
const { binarySearch } = require('./binary_search');

const range = Array.from({ length: 500 }, (_, i) => i * 2);
const cases = [
    [[], 1, -1],
    [[4], 4, 0],
    [[4], 5, -1],
    [[1, 3, 5, 7, 9], 1, 0],
    [[1, 3, 5, 7, 9], 9, 4],
    [[1, 3, 5, 7, 9], 6, -1],
    [range, 998, 499],
];

for (const [a, target, expected] of cases) {
    assert.strictEqual(binarySearch(a, target), expected, `binarySearch([${a.slice(0, 5)}...], ${target})`);
}

console.log(`All ${cases.length} checks passed.`);

Source: Zerethon Official Sample. Algorithm as shown in the Zerethon Tools Binary Search Visualizer.