Skip to content

Instantly share code, notes, and snippets.

@aadebdeb
Created March 29, 2019 15:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aadebdeb/964ff754d4045e2b7b1fea8044e7420d to your computer and use it in GitHub Desktop.
Save aadebdeb/964ff754d4045e2b7b1fea8044e7420d to your computer and use it in GitHub Desktop.
binary search to find index range from array with duplicated values in JavaScript
function binarysearchMinIndex(array, target, from, to) {
while (from !== to) {
const middle = from + Math.floor((to - from) / 2);
if (array[middle] < target) {
from = middle + 1;
} else {
to = middle;
}
}
if (array[from] === target) {
return from;
} else {
return -1;
}
}
function binarysearchMaxIndex(array, target, from, to) {
while (from !== to) {
const middle = from + Math.ceil((to - from) / 2);
if (array[middle] > target) {
to = middle - 1;
} else {
from = middle;
}
}
if (array[from] === target) {
return from;
} else {
return -1;
}
}
function binarysearchRange(array, target) {
const from = binarysearchMinIndex(array, target, 0, array.length - 1);
const to = from !== -1 ? binarysearchMaxIndex(array, target, from, array.length - 1) : -1;
return { from: from, to: to };
}
function linearsearch(array, target) {
let from = -1;
let to = -1;
for (let i = 0; i < array.length; i++) {
if (array[i] === target) {
from = i;
break;
}
}
for (let i = array.length - 1; i >= 0; i--) {
if (array[i] === target) {
to = i;
break;
}
}
return { from: from, to: to };
}
// test
const array = Array.from({length: 512}, () => {
return Math.floor(Math.random() * 64.0);
}).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
for (let i = -100; i < 100; i++) {
const actual = binarysearchRange(array, i);
const expected = linearsearch(array, i);
if (actual.from !== expected.from || actual.to !== expected.to) {
console.error('not correct');
}
}
@aadebdeb
Copy link
Author

ordinary binary search

function binarysearch(array, target) {
  let from = 0;
  let to = array.length - 1;
  while (from <= to) {
    const middle = from + Math.floor((to - from) / 2);
    if (array[middle] < target) {
      from = middle + 1;
    } else if (array[middle] > target) {
      to = middle - 1;
    } else {
      return middle;
    }
  }
  return -1;
}


// test 
let x = 0;
const array = Array.from({length: 512}, () => {
   x += Math.floor(Math.random() * 2.0) + 1;
  return x;
});

for (let i = 0; i < 10000; i++) {
  if (binarysearch(array, i) !== array.indexOf(i)) {
    console.error('not correct');
  }
}

@aadebdeb
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment