From 0fa510bd60713200e85ba5f20dc0edc5fc3dae54 Mon Sep 17 00:00:00 2001 From: prisojacques <76072668+prisojacques@users.noreply.github.com> Date: Sat, 1 Jul 2023 07:26:24 +0200 Subject: [PATCH] feat: add quick select algorithm and test #6 (#140) * feat: add quick select algorithm and test #6 * feat: update quick select algorithm and test #6 --- sorts/quick_select.ts | 40 +++++++++++++++++++++++++++++++++ sorts/test/quick_select.test.ts | 29 ++++++++++++++++++++++++ 2 files changed, 69 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..23381ee2 --- /dev/null +++ b/sorts/quick_select.ts @@ -0,0 +1,40 @@ +import {partition} from "./quick_sort"; +/** + * @function QuickSelect + * @description is an algorithm based on the QuickSort approach that selects the kth smallest element from an array + * @param {number[]} array - The array from which to select the element + * @param {number} k - The index representing the kth smallest element to find + * @param {number} left - The left boundary of the array or subarray to consider (default: 0) + * @param {number} right - The right boundary of the array or subarray to consider (default: array.length - 1) + * @returns {number} - The kth smallest element from the array + * @throws {Error} - If k is out of bounds (less than 0 or greater than or equal to array.length) + */ + +export const QuickSelect = ( + array: number[], + k: number, + left: number = 0, + right: number = array.length - 1 +):number => { + if(k < 0 || k >= array.length) { + throw new Error('k is out of bounds'); + } + if (left === right) { + // If the list contains only one element, return that element + return array[left]; + } + + // Partition the array + let pivotIndex = partition(array, left, right); + + // The pivot is in its final sorted position + if (k === pivotIndex) { + return array[k]; + } else if (k < pivotIndex) { + // If k is less than the pivot index, look left + return QuickSelect(array, k, left, pivotIndex - 1); + } else { + // If k is greater than the pivot index, look right + return QuickSelect(array, k, pivotIndex + 1, right); + } +}; diff --git a/sorts/test/quick_select.test.ts b/sorts/test/quick_select.test.ts new file mode 100644 index 00000000..885ed5e1 --- /dev/null +++ b/sorts/test/quick_select.test.ts @@ -0,0 +1,29 @@ +import { QuickSelect } from "../quick_select"; + +describe('QuickSelect', () => { + test('should return the kth smallest element in an array', () => { + const array = [8, 3, 5, 1, 4, 2]; + expect(QuickSelect(array, 0)).toBe(1); + expect(QuickSelect(array, 1)).toBe(2); + expect(QuickSelect(array, 2)).toBe(3); + expect(QuickSelect(array, 3)).toBe(4); + expect(QuickSelect(array, 4)).toBe(5); + expect(QuickSelect(array, 5)).toBe(8); + }); + + test('should work with arrays of size 1', () => { + const array = [4]; + expect(QuickSelect(array, 0)).toBe(4); + }); + + test('should work with large arrays', () => { + const array = Array.from({length: 1000}, (_, i) => i + 1); + expect(QuickSelect(array, 499)).toBe(500); + }); + + test('should throw error when k is out of bounds', () => { + const array = [8, 3, 5, 1, 4, 2]; + expect(() => QuickSelect(array, -1)).toThrow(); + expect(() => QuickSelect(array, 6)).toThrow(); + }); +});