diff --git a/DIRECTORY.md b/DIRECTORY.md index 5b8240d8d..dea092360 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -178,6 +178,7 @@ * [InterpolationSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/InterpolationSearch.js) * [JumpSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/JumpSearch.js) * [LinearSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/LinearSearch.js) + * [QuickSelect](https://github.com/TheAlgorithms/Javascript/blob/master/Search/QuickSelectSearch.js) * [StringSearch](https://github.com/TheAlgorithms/Javascript/blob/master/Search/StringSearch.js) ## Sorts diff --git a/Search/QuickSelectSearch.js b/Search/QuickSelectSearch.js new file mode 100644 index 000000000..724fb8d13 --- /dev/null +++ b/Search/QuickSelectSearch.js @@ -0,0 +1,55 @@ +/* + * Places the `k` smallest elements in `array` in the first `k` indices: `[0..k-1]` + * Modifies the passed in array *in place* + * Returns a slice of the wanted elements for convenience + * Efficient mainly because it never performs a full sort. + * + * The only guarantees are that: + * + * - The `k`th element is in its final sort index (if the array were to be sorted) + * - All elements before index `k` are smaller than the `k`th element + * + * [Reference](http://en.wikipedia.org/wiki/Quickselect) + */ +function quickSelectSearch(array, k) { + if (!array || array.length <= k) { + throw new Error('Invalid arguments'); + } + + let from = 0; + let to = array.length - 1; + while (from < to) { + let left = from; + let right = to; + const pivot = array[Math.ceil((left + right) * 0.5)]; + + while (left < right) { + if (array[left] >= pivot) { + const tmp = array[left]; + array[left] = array[right]; + array[right] = tmp; + --right; + } else { + ++left; + } + } + + if (array[left] > pivot) { + --left; + } + + if (k <= left) { + to = left; + } else { + from = left + 1; + } + } + return array; +} + +/* ---------------------------------- Test ---------------------------------- */ + +const arr = [1121111, 21, 333, 41, 5, 66, 7777, 28, 19, 11110] +console.log(quickSelectSearch(arr, 5)); // [ 19, 21, 28, 41, 5, 66, 333, 11110, 1121111, 7777 ] +console.log(quickSelectSearch(arr, 2)); // [ 19, 5, 21, 41, 28, 333, 11110, 1121111, 7777, 66 ] +console.log(quickSelectSearch(arr, 7)); // [ 19, 5, 21, 41, 28, 66, 333, 7777, 11110, 1121111 ]