From f2c60e1f46114bc96de913e952ce726bd88c4aae Mon Sep 17 00:00:00 2001 From: Jacques Priso Date: Mon, 26 Jun 2023 19:31:55 +0200 Subject: [PATCH] feat: add quick select algorithm and test #6 --- sorts/quick_select.ts | 54 +++++++++++++++++++++++++++++++++ sorts/test/quick_select.test.ts | 18 +++++++++++ 2 files changed, 72 insertions(+) create mode 100644 sorts/quick_select.ts create mode 100644 sorts/test/quick_select.test.ts diff --git a/sorts/quick_select.ts b/sorts/quick_select.ts new file mode 100644 index 00000000..e1306c92 --- /dev/null +++ b/sorts/quick_select.ts @@ -0,0 +1,54 @@ +/** + * @function partition + * @description is a helper function used in the QuickSelect algorithm to partition the array around a pivot element + * @param {number[]} arr - The array to partition + * @param {number} left - The left boundary of the partition range + * @param {number} right - The right boundary of the partition range + * @param {number} pivotIndex - The index of the pivot element + * @returns {number} - The new index of the pivot element after partitioning + */ + +function partition(arr: number[], left: number, right: number, pivotIndex: number): number { + const pivotValue = arr[pivotIndex]; + [arr[pivotIndex], arr[right]] = [arr[right], arr[pivotIndex]]; + let storeIndex = left; + + for (let i = left; i < right; i++) { + if (arr[i] < pivotValue) { + [arr[i], arr[storeIndex]] = [arr[storeIndex], arr[i]]; + storeIndex++; + } + } + + [arr[storeIndex], arr[right]] = [arr[right], arr[storeIndex]]; + return storeIndex; +} + +/** + * @function quickSelect + * @description is an algorithm based on the QuickSort approach that selects the kth smallest element from an array + * @param {number[]} arr - The array from which to select the element + * @param {number} left - The left boundary of the array or subarray to consider + * @param {number} right - The right boundary of the array or subarray to consider + * @param {number} k - The index representing the kth smallest element to find + * @returns {number} - The kth smallest element from the array + */ + +export function quickSelect(arr: number[], left: number, right: number, k: number): number { + if (left === right) { + return arr[left]; + } + + const pivotIndex = Math.floor(Math.random() * (right - left + 1)) + left; + const pivotNewIndex = partition(arr, left, right, pivotIndex); + + if (k === pivotNewIndex) { + return arr[k]; + } else if (k < pivotNewIndex) { + return quickSelect(arr, left, pivotNewIndex - 1, k); + } else { + return quickSelect(arr, pivotNewIndex + 1, right, k); + } +} + + diff --git a/sorts/test/quick_select.test.ts b/sorts/test/quick_select.test.ts new file mode 100644 index 00000000..99313370 --- /dev/null +++ b/sorts/test/quick_select.test.ts @@ -0,0 +1,18 @@ +import { quickSelect } from "../quick_select"; + +describe("Quick Select", () => { + + it("should return the correct value for worst case", () => { + const arr = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; + const k = 2; // kth smallest element + + expect(quickSelect(arr, 0, arr.length - 1, k)).toBe(3); + }); + + it("should return the correct value for best case", () => { + const arr = [1, 4, 2, 9, 5, 7, 3, 8, 10, 6]; + const k = 5; // kth smallest element + + expect(quickSelect(arr, 0, arr.length - 1, k)).toBe(6); + }); +});