lgrthms
Version:
Algorithms and data structures for your JavaScript and TypeScript projects 🧑💻
140 lines (139 loc) • 4.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.searchForRange = exports.binarySearchLastIndex = exports.binarySearchLast = exports.binarySearchFirstIndex = exports.binarySearchFirst = exports.shiftedBinarySearchIndex = exports.shiftedBinarySearch = exports.binarySearchIndex = exports.binarySearch = void 0;
function binarySearch(array, target, get) {
const index = binarySearchIndex(array, target, get);
return index !== -1 ? array[index] : undefined;
}
exports.binarySearch = binarySearch;
function binarySearchIndex(array, target, get) {
let leftIdx = 0;
let rightIdx = array.length - 1;
get = get ? get : (element) => element;
while (leftIdx <= rightIdx) {
const middleIdx = Math.floor((leftIdx + rightIdx) / 2);
const element = array[middleIdx];
const value = get(element);
if (target === value) {
return middleIdx;
}
if (target < value) {
rightIdx = middleIdx - 1;
}
else {
leftIdx = middleIdx + 1;
}
}
return -1;
}
exports.binarySearchIndex = binarySearchIndex;
function shiftedBinarySearch(array, target, get) {
const index = shiftedBinarySearchIndex(array, target, get);
return index !== -1 ? array[index] : undefined;
}
exports.shiftedBinarySearch = shiftedBinarySearch;
function shiftedBinarySearchIndex(array, target, get) {
let leftIdx = 0;
let rightIdx = array.length - 1;
get = get ? get : (element) => element;
while (leftIdx <= rightIdx) {
const middleIdx = Math.floor((leftIdx + rightIdx) / 2);
const middleValue = get(array[middleIdx]);
if (target === middleValue) {
return middleIdx;
}
const leftValue = get(array[leftIdx]);
const rightValue = get(array[rightIdx]);
if (leftValue <= middleValue) {
if (target < middleValue && target >= leftValue) {
rightIdx = middleIdx - 1;
}
else {
leftIdx = middleIdx + 1;
}
}
else {
if (target > middleValue && target <= rightValue) {
leftIdx = middleIdx + 1;
}
else {
rightIdx = middleIdx - 1;
}
}
}
return -1;
}
exports.shiftedBinarySearchIndex = shiftedBinarySearchIndex;
function binarySearchFirst(array, target, get) {
const index = binarySearchFirstIndex(array, target, get);
return index !== -1 ? array[index] : undefined;
}
exports.binarySearchFirst = binarySearchFirst;
function binarySearchFirstIndex(array, target, get) {
let leftIdx = 0;
let rightIdx = array.length - 1;
get = get ? get : (element) => element;
while (leftIdx <= rightIdx) {
const middleIdx = Math.floor((leftIdx + rightIdx) / 2);
const middleValue = get(array[middleIdx]);
if (target === middleValue) {
if (middleIdx === 0) {
return middleIdx;
}
const middlePreviousValue = get(array[middleIdx - 1]);
if (target === middlePreviousValue) {
rightIdx = middleIdx - 1;
}
else {
return middleIdx;
}
}
if (target < middleValue) {
rightIdx = middleIdx - 1;
}
else {
leftIdx = middleIdx + 1;
}
}
return -1;
}
exports.binarySearchFirstIndex = binarySearchFirstIndex;
function binarySearchLast(array, target, get) {
const index = binarySearchLastIndex(array, target, get);
return index !== -1 ? array[index] : undefined;
}
exports.binarySearchLast = binarySearchLast;
function binarySearchLastIndex(array, target, get) {
let leftIdx = 0;
let rightIdx = array.length - 1;
get = get ? get : (element) => element;
while (leftIdx <= rightIdx) {
const middleIdx = Math.floor((leftIdx + rightIdx) / 2);
const middleValue = get(array[middleIdx]);
if (target === middleValue) {
if (middleIdx === array.length - 1) {
return middleIdx;
}
const middleNextValue = get(array[middleIdx + 1]);
if (target === middleNextValue) {
leftIdx = middleIdx + 1;
}
else {
return middleIdx;
}
}
if (target < middleValue) {
rightIdx = middleIdx - 1;
}
else {
leftIdx = middleIdx + 1;
}
}
return -1;
}
exports.binarySearchLastIndex = binarySearchLastIndex;
function searchForRange(array, target, get) {
get = get ? get : (element) => element;
return [binarySearchFirstIndex(array, target, get), binarySearchLastIndex(array, target, get)];
}
exports.searchForRange = searchForRange;