From f53cf76a713bdad5916a7f0259dd8c824869c713 Mon Sep 17 00:00:00 2001 From: Anwar Ahmed Date: Sun, 15 Sep 2024 21:37:24 +0300 Subject: [PATCH 1/2] feat: add function to choose better pivot and interface for the module --- Sorts/QuickSortRecursive.js | 53 +++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/Sorts/QuickSortRecursive.js b/Sorts/QuickSortRecursive.js index e45dc34dac..94aba3aff1 100644 --- a/Sorts/QuickSortRecursive.js +++ b/Sorts/QuickSortRecursive.js @@ -15,22 +15,39 @@ Problem & Source of Explanation => https://www.cs.auckland.ac.nz/software/AlgAnim/qsort1a.html */ + /** - * Partition in place QuickSort. - * @param {number[]} inputList list of values. - * @param {number} low lower index for partition. - * @param {number} high higher index for partition. + * Sorts the input list using the quicksort algorithm. + * + * @param {Array} inputList - the list to be sorted + * @return {Array} the sorted list */ -const quickSort = (inputList, low, high) => { +// encapsulate the main function to to be the interface of our module +const quickSort = (inputList) => { if (!Array.isArray(inputList)) { throw new TypeError('Please input a valid list or array.') } + return quickSortHelper(inputList, 0, inputList.length - 1) +} + + +/** + * Recursively sorts the input list using the quicksort algorithm. + * + * @param {number[]} inputList - the list to be sorted + * @param {number} low - the lower index of the current partition + * @param {number} high - the higher index of the current partition + * @return {number[]} the sorted list + */ + +const quickSortHelper = (inputList, low, high) => { + // base case if (low < high) { // get the partition index. const pIndex = partition(inputList, low, high) // recursively call the quickSort method again. - quickSort(inputList, low, pIndex - 1) - quickSort(inputList, pIndex + 1, high) + quickSortHelper(inputList, low, pIndex - 1) + quickSortHelper(inputList, pIndex + 1, high) } return inputList } @@ -43,7 +60,9 @@ const quickSort = (inputList, low, high) => { * @returns {number} `pIndex` pivot index value. */ const partition = (partitionList, low, high) => { - const pivot = partitionList[high] + let mid =Math.floor((low + high) / 2) + // get the median of three is good technique for partitioning to be sure that the 2 sub-arrays will be almost equal or near + const pivot = medianOfThree(partitionList, low, mid, high) let pIndex = low for (let index = low; index <= high - 1; index++) { if (partitionList[index] < pivot) { @@ -62,4 +81,22 @@ const partition = (partitionList, low, high) => { return pIndex } + +/** + * Returns the median value of three elements in an array. + * + * @param {number[]} arr - the input array + * @param {number} low - the index of the first element + * @param {number} mid - the index of the second element + * @param {number} high - the index of the third element + * @return {number} the median value of the three elements + */ + +const medianOfThree = (partitionList, low,mid, high) => { + const a = partitionList[low], b = partitionList[mid], c = partitionList[high]; + if ((a > b) !== (a > c)) return a; + else if ((b > a) !== (b > c)) return b; + else return c; +} + export { quickSort } From cc0700360ebcbb46a722fecafa939d7baef9adf6 Mon Sep 17 00:00:00 2001 From: Anwar Ahmed Date: Sun, 15 Sep 2024 22:07:48 +0300 Subject: [PATCH 2/2] fix: refactor the test cases with adding interface for the module --- Sorts/test/QuickSortRecursive.test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sorts/test/QuickSortRecursive.test.js b/Sorts/test/QuickSortRecursive.test.js index 7516877a11..5e258dce03 100644 --- a/Sorts/test/QuickSortRecursive.test.js +++ b/Sorts/test/QuickSortRecursive.test.js @@ -2,13 +2,13 @@ import { quickSort } from '../QuickSortRecursive' describe('QuickSortRecursive | Partition In Place Method', () => { it('Expectedly, throw some error if we pass a non-array input', () => { - expect(() => quickSort('xyz', 0, 2)).toThrow( + expect(() => quickSort('xyz')).toThrow( 'Please input a valid list or array.' ) - expect(() => quickSort(null, 0, 4)).toThrow( + expect(() => quickSort(null)).toThrow( 'Please input a valid list or array.' ) - expect(() => quickSort(55, 0, 2)).toThrow( + expect(() => quickSort(55)).toThrow( 'Please input a valid list or array.' ) }) @@ -16,7 +16,7 @@ describe('QuickSortRecursive | Partition In Place Method', () => { it('Expectedly, the quickSort method will sort the unsorted list in ascending order', () => { const unSortArray = [5, 9, 3, 4, 6, 2, 0, 1, 7, 8] const sortedExpectedArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - expect(quickSort(unSortArray, 0, unSortArray.length - 1)).toEqual( + expect(quickSort(unSortArray)).toEqual( sortedExpectedArray ) }) @@ -24,7 +24,7 @@ describe('QuickSortRecursive | Partition In Place Method', () => { it('Expectedly, the quickSort method will arrange the list of character values in dictionary order.', () => { const unSortList = ['d', 'e', 'c', 'a', 'f', 'b'] const sortedExpectedList = ['a', 'b', 'c', 'd', 'e', 'f'] - expect(quickSort(unSortList, 0, unSortList.length - 1)).toEqual( + expect(quickSort(unSortList)).toEqual( sortedExpectedList ) })