HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Binary Search Algorithm in JavaScript

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
javascriptalgorithmbinarysearch

Problem

I've written this implementation of a binary search algorithm, and wanted to know if it was efficient and where I can improve.

function search(el, list) {
    // list = list || LIST;
    var LIM = Math.ceil(Math.log2(list.length)),
        lb = 0,
        ub = list.length - 1,
        i;
    while (el !== list[i = ~~((lb + ub) / 2)] && el !== list[++i]) {
        if (!--LIM) return ("NOT FOUND");
        if (el > list[i]) lb = i;
        else ub = i;
    }
    return i;
}

Solution

What doesn't work properly

As pointed by @Roland Illig's answer, your solution produces an error when list contains only 1 item and this item doesn't match el.

It comes from the fact that:

  • for a 1-item list, LIM is 0



  • after the while() expression didn't find a match, --LIM gives -1, which evaluates to true



  • so if (!--LIM) is false and the loop continues infinitely...



This issue can be solved by merely changing this test to if (--LIM

  • LIM to tries (also note that using uppercase is supposed to be reserved for constants, while this data is not)



  • lb to lowerBound



  • ub to upperBound



Also, following best practices, I recommend to use block marks for
if()`s.

All that said, here is a suggested improved (and corrected) version:

function search(searchedValue, list) {
    var tries = Math.ceil(Math.log2(list.length)),
        lowerBound = 0,
        upperBound = list.length - 1,
        i;
    while (
        searchedValue !== list[i = ~~((lowerBound + upperBound) / 2)]
    &&
        searchedValue !== list[++i]
    ) {
        if (--tries  list[i]) {
            lowerBound = i;
        } else {
            upperBound = i;
        }
    }
    return i;
}

Code Snippets

function search(searchedValue, list) {
    var tries = Math.ceil(Math.log2(list.length)),
        lowerBound = 0,
        upperBound = list.length - 1,
        i;
    while (
        searchedValue !== list[i = ~~((lowerBound + upperBound) / 2)]
    &&
        searchedValue !== list[++i]
    ) {
        if (--tries <= 0) {
            return ("NOT FOUND");
        }
        if (searchedValue > list[i]) {
            lowerBound = i;
        } else {
            upperBound = i;
        }
    }
    return i;
}

Context

StackExchange Code Review Q#150980, answer score: 4

Revisions (0)

No revisions yet.