Last active
March 26, 2020 10:18
-
-
Save khalid32/a47d80c5cb053f686f00c43b597b5c0e to your computer and use it in GitHub Desktop.
Famous algorithms in javascript...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Binary Search */ | |
/* Typical comparison function */ | |
let defaultCompare = (a, b) => a > b ? 1 : (a < b ? -1 : 0); | |
// Binary Search With Loop | |
let binarySearch = (array, element, compare = defaultCompare) => { | |
let left = 0; | |
let right = array.length - 1; | |
while (left <= right) { | |
let middle = Math.floor((right + left) / 2); | |
switch (compare(element, array[middle])) { | |
case -1: { right = middle - 1; break; } | |
case 1: { left = middle + 1; break; } | |
default: { return middle; } | |
} | |
} | |
return -1; | |
}; | |
// Binary Search With Recursion | |
let binarySearch = (array, element, compare = defaultCompare, left = 0, right = array.length - 1) => { | |
if (left > right) { return -1; } | |
const middle = Math.floor((right + left) / 2); | |
const comparison = compare(element, array[middle]); | |
return ( | |
comparison === -1 ? | |
binarySearch(array, element, compare, left, middle - 1) | |
: comparison === 1 ? | |
binarySearch(array, element, compare, middle + 1, right) | |
: | |
middle | |
); | |
}; | |
// Binary Search With Tail Recursion | |
let binarySearch = (array, element, compare = defaultCompare, left = 0, right = array.length - 1) => { | |
if (left > right) { return -1; } | |
const middle = Math.floor((right + left) / 2); | |
const comparison = compare(element, array[middle]); | |
if (comparison === 0) { return middle; } | |
const newBounds = comparison === -1 | |
? [left, middle - 1] | |
: [middle + 1, right]; | |
return binarySearch(array, element, compare, ...newBounds); | |
}; | |
// Binary Search With Array Splitting | |
let binarySearch = (array, element, compare = defaultCompare) => { | |
if (array.length === 0) { return -1; } | |
const middle = Math.floor(array.length / 2); | |
const comparison = compare(element, array[middle]); | |
if (comparison === 0) { return middle; } | |
const [left, right] = comparison === -1 ? [0, middle - 1] : [middle + 1, array.length]; | |
const subIndex = binarySearch(array.slice(left, right), element, compare); | |
return subIndex === -1 ? -1 : left + subIndex; | |
}; | |
// with Array View | |
export let ArrayView = ( | |
array, | |
start = 0, | |
end = array.length, | |
) => ({ | |
length: end - start, | |
toArray: () => array.slice(start, end), | |
slice: (dStart, dEnd) => | |
ArrayView(array, start + dStart, start + dEnd), | |
get: (index) => { | |
let realIndex = start + index; | |
return realIndex < end && realIndex >= start | |
? array[realIndex] | |
: undefined | |
; | |
}, | |
}); | |
let binarySearchWithArrayView = (array, ...args) => | |
binarySearchWithArraySplitting(ArrayView(array), ...args) | |
let binarySearchWithArraySplitting = (array, element, compare = defaultCompare) => { | |
if (array.length === 0) { return -1; } | |
const middle = Math.floor(array.length / 2); | |
const comparison = compare(element, array.get(middle)); | |
if (comparison === 0) { return middle; } | |
const [left, right] = comparison === -1 | |
? [0, middle - 1] | |
: [middle + 1, array.length]; | |
const subIndex = binarySearchWithArraySplitting(array.slice(left, right), element, compare); | |
return subIndex === -1 | |
? -1 | |
: left + subIndex; | |
}; | |
binarySearch([], 2) // -1 | |
binarySearch([1], 1) // 0 | |
binarySearch([1], 2) // -1 | |
binarySearch([1,2,3], 2) // 1 | |
binarySearch([1,2,3], 3) // 2 | |
binarySearch([1,2,3], 4) // -1 | |
binarySearch([1,2,3,7], 3) // 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment