diff --git a/DIRECTORY.md b/DIRECTORY.md index 6c1fa7aeb8..7f6484cae5 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -35,6 +35,8 @@ * [ROT13](Ciphers/ROT13.js) * [VigenereCipher](Ciphers/VigenereCipher.js) * [XORCipher](Ciphers/XORCipher.js) +* **Compression** + * [RLE](Compression/RLE.js) * **Conversions** * [ArbitraryBase](Conversions/ArbitraryBase.js) * [ArrayBufferToBase64](Conversions/ArrayBufferToBase64.js) @@ -285,6 +287,7 @@ * [Problem016](Project-Euler/Problem016.js) * [Problem017](Project-Euler/Problem017.js) * [Problem018](Project-Euler/Problem018.js) + * [Problem019](Project-Euler/Problem019.js) * [Problem020](Project-Euler/Problem020.js) * [Problem021](Project-Euler/Problem021.js) * [Problem023](Project-Euler/Problem023.js) diff --git a/Sorts/QuickSort.js b/Sorts/QuickSort.js index 3885054e36..a5af2dc9d1 100644 --- a/Sorts/QuickSort.js +++ b/Sorts/QuickSort.js @@ -1,30 +1,46 @@ /** - * @function QuickSort + * @function quickSort * @description Quick sort is a comparison sorting algorithm that uses a divide and conquer strategy. - * @param {Integer[]} items - Array of integers + * This version optimizes space complexity by sorting the array in place. + * @param {Integer[]} items - Array of integers to be sorted. + * @param {number} left - The starting index (defaults to 0). + * @param {number} right - The ending index (defaults to array length - 1). * @return {Integer[]} - Sorted array. * @see [QuickSort](https://en.wikipedia.org/wiki/Quicksort) */ -function quickSort(items) { - const length = items.length +function quickSort(items, left = 0, right = items.length - 1) { + if (left < right) { + let pivotIndex = partition(items, left, right) - if (length <= 1) { - return items + quickSort(items, left, pivotIndex - 1) + quickSort(items, pivotIndex + 1, right) } - const PIVOT = items[0] - const GREATER = [] - const LESSER = [] + return items +} + +/** + * @function partition + * @description This function partitions the array using the last element as the pivot. + * It ensures that all elements smaller than the pivot are on the left side, + * and all greater elements are on the right side. + * @param {Integer[]} items - Array of integers to partition. + * @param {number} left - The starting index for partitioning. + * @param {number} right - The ending index for partitioning. + * @return {number} - The index of the pivot element after partitioning. + */ +function partition(items, left, right) { + const pivot = items[right] + let i = left - 1 - for (let i = 1; i < length; i++) { - if (items[i] > PIVOT) { - GREATER.push(items[i]) - } else { - LESSER.push(items[i]) + for (let j = left; j < right; j++) { + if (items[j] <= pivot) { + i++ + ;[items[i], items[j]] = [items[j], items[i]] } } - const sorted = [...quickSort(LESSER), PIVOT, ...quickSort(GREATER)] - return sorted + ;[items[i + 1], items[right]] = [items[right], items[i + 1]] + return i + 1 } export { quickSort } diff --git a/Sorts/QuickSortRecursive.js b/Sorts/QuickSortRecursive.js index e45dc34dac..4034aca58c 100644 --- a/Sorts/QuickSortRecursive.js +++ b/Sorts/QuickSortRecursive.js @@ -1,65 +1,51 @@ -/* - 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. + * @function quickSort + * @description Quick sort is a comparison sorting algorithm that uses a divide and conquer strategy. + * This version optimizes space complexity by sorting the array in place. + * @param {Integer[]} items - Array of integers to be sorted. + * @param {number} left - The starting index (defaults to 0). + * @param {number} right - The ending index (defaults to array length - 1). + * @return {Integer[]} - Sorted array. + * @throws Will throw an error if the input is not an array. + * @see [QuickSort](https://en.wikipedia.org/wiki/Quicksort) */ -const quickSort = (inputList, low, high) => { - if (!Array.isArray(inputList)) { - throw new TypeError('Please input a valid list or array.') +function quickSort(items, left = 0, right = items.length - 1) { + if (!Array.isArray(items)) { + throw new Error('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) + + if (left < right) { + let pivotIndex = partition(items, left, right) + quickSort(items, left, pivotIndex - 1) + quickSort(items, pivotIndex + 1, right) } - return inputList + + return items } /** - * Partition In Place method. - * @param {number[]} partitionList list for partitioning. - * @param {number} low lower index for partition. - * @param {number} high higher index for partition. - * @returns {number} `pIndex` pivot index value. + * @function partition + * @description This function partitions the array using the last element as the pivot. + * It ensures that all elements smaller than the pivot are on the left side, + * and all greater elements are on the right side. + * @param {Integer[]} items - Array of integers to partition. + * @param {number} left - The starting index for partitioning. + * @param {number} right - The ending index for partitioning. + * @return {number} - The index of the pivot element after partitioning. */ -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 +function partition(items, left, right) { + const pivot = items[right] + let i = left - 1 + + for (let j = left; j < right; j++) { + if (items[j] <= pivot) { + i++ + ;[items[i], items[j]] = [items[j], items[i]] } } - ;[partitionList[pIndex], partitionList[high]] = [ - partitionList[high], - partitionList[pIndex] - ] - return pIndex + + ;[items[i + 1], items[right]] = [items[right], items[i + 1]] + return i + 1 } export { quickSort } diff --git a/package-lock.json b/package-lock.json index 9a4fd732a9..3513680ee2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "devDependencies": { "@vitest/coverage-v8": "^1.2.1", "globby": "^13.2.2", - "husky": "^8.0.3", + "husky": "^9.1.6", "prettier": "^3.0.3", "vitest": "^1.2.1" }, @@ -732,14 +732,16 @@ "license": "MIT" }, "node_modules/husky": { - "version": "8.0.3", + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", + "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==", "dev": true, "license": "MIT", "bin": { - "husky": "lib/bin.js" + "husky": "bin.js" }, "engines": { - "node": ">=14" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/typicode" diff --git a/package.json b/package.json index e667e1eea2..e1af2c378e 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,11 @@ "author": "TheAlgorithms", "license": "GPL-3.0", "devDependencies": { + "@vitest/coverage-v8": "^1.2.1", "globby": "^13.2.2", - "husky": "^8.0.3", + "husky": "^9.1.6", "prettier": "^3.0.3", - "vitest": "^1.2.1", - "@vitest/coverage-v8": "^1.2.1" + "vitest": "^1.2.1" }, "engines": { "node": ">=20.6.0"