diff --git a/Sorts/QuickSortRecursive.js b/Sorts/QuickSortRecursive.js new file mode 100644 index 000000000..1ab3f4a8e --- /dev/null +++ b/Sorts/QuickSortRecursive.js @@ -0,0 +1,59 @@ +/* + Quicksort is the most popular sorting algorithm and there have + lots of different implementations but the "recursive" or "Partition in place" + is one of the most efficient implementations below we have discussed how to + implement it. + + Partition in place => "in place" Partition in place indicates that we + do not need any other space to store the auxiliary array and the term + "partition" denotes that we split the list into two parts one is less + than the pivot and the other is greater than the pivot and repeats this + process recursively and breaks the problem into sub-problems and makes + it singular so that the behavior or "divide and conquer" get involved + too. + + 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. + */ +const quickSort = (inputList, low, high) => { + if (!Array.isArray(inputList)) { + throw new TypeError('Please input a valid list or array.') + } + 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) + } + return inputList +} + +/** + * Partition In Place method. + * @param {number[]} partitionList list for partiting. + * @param {number} low lower index for partition. + * @param {number} high higher index for partition. + * @returns {number} `pIndex` pivot index value. + */ +const partition = (partitionList, low, high) => { + const pivot = partitionList[high] + let pIndex = low + for (let index = low; index <= high - 1; index++) { + if (partitionList[index] < pivot) { + // swap variables using array destructuring + [partitionList[index], partitionList[pIndex]] = [partitionList[pIndex], partitionList[index]] + pIndex += 1 + } + } + [partitionList[pIndex], partitionList[high]] = [partitionList[high], partitionList[pIndex]] + return pIndex +} + +export { quickSort } diff --git a/Sorts/QuickSortRecursive.test.js b/Sorts/QuickSortRecursive.test.js new file mode 100644 index 000000000..d82299aa3 --- /dev/null +++ b/Sorts/QuickSortRecursive.test.js @@ -0,0 +1,21 @@ +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('Please input a valid list or array.') + expect(() => quickSort(null, 0, 4)).toThrow('Please input a valid list or array.') + expect(() => quickSort(55, 0, 2)).toThrow('Please input a valid list or array.') + }) + + 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(sortedExpectedArray) + }) + + 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(sortedExpectedList) + }) +})