From 13caa78caa6d1f2dc5b13707066acc2f76c588ad Mon Sep 17 00:00:00 2001 From: Ansh Tyagi Date: Sun, 1 Oct 2023 17:31:12 +0530 Subject: [PATCH 1/3] feat: add Random Pivot Quick Sort --- sorts/random_pivot_quick_sort.ts | 74 ++++++++++++++++++++++ sorts/test/random_pivot_quick_sort.test.ts | 15 +++++ 2 files changed, 89 insertions(+) create mode 100644 sorts/random_pivot_quick_sort.ts create mode 100644 sorts/test/random_pivot_quick_sort.test.ts diff --git a/sorts/random_pivot_quick_sort.ts b/sorts/random_pivot_quick_sort.ts new file mode 100644 index 00000000..08c11c4c --- /dev/null +++ b/sorts/random_pivot_quick_sort.ts @@ -0,0 +1,74 @@ +/** + * @function partition + * @description Partitions an array by selecting a random pivot element. + * @param {number[]} array - The array to partition. + * @param {number} left - The left index of the subarray. + * @param {number} right - The right index of the subarray. + * @returns {number} - The index of the pivot element after partitioning. + */ +export const partition = ( + array: number[], + left: number = 0, + right: number = array.length - 1 +): number => { + // Select a random pivot element within the subarray. + const randomPivot = array[Math.floor(Math.random() * (right - left + 1)) + left]; + let i = left; + let j = right; + + while (i <= j) { + while (array[i] < randomPivot) { + i++; + } + + while (array[j] > randomPivot) { + j--; + } + + if (i <= j) { + // Swap elements at indices i and j. + [array[i], array[j]] = [array[j], array[i]]; + i++; + j--; + } + } + + return i; +}; + +/** + * @function randomPivotQuickSort + * @description Sorts an array using the Quick Sort algorithm with random pivoting. + * @param {number[]} array - The array to sort. + * @param {number} left - The left index of the subarray. + * @param {number} right - The right index of the subarray. + * @returns {number[]} - The sorted array. + * @complexity_analysis + * Time complexity: + * - Best case: O(n log n) : Similar to the normal Quick Sort, the best case occurs when the pivot chosen in each step divides the array into roughly equal halves. + * - Average case: O(n log n) : This is also similar to the normal Quick Sort, but with a different constant factor due to random pivot selection. + * - Worst case: O(n^2) : The worst case can still be O(n^2) if, by random chance, the pivot selections repeatedly lead to unbalanced partitions. + * However, the worst-case scenario is less likely to occur in practice compared to the normal Quick Sort because of the random pivot selection. + * Space complexity: O(n log n) + */ +export const randomPivotQuickSort = ( + array: number[], + left: number = 0, + right: number = array.length - 1 +): number[] => { + let index; + + if (array.length > 1) { + index = partition(array, left, right); + + if (left < index - 1) { + randomPivotQuickSort(array, left, index - 1); + } + + if (index < right) { + randomPivotQuickSort(array, index, right); + } + } + + return array; +}; diff --git a/sorts/test/random_pivot_quick_sort.test.ts b/sorts/test/random_pivot_quick_sort.test.ts new file mode 100644 index 00000000..b7f93a68 --- /dev/null +++ b/sorts/test/random_pivot_quick_sort.test.ts @@ -0,0 +1,15 @@ +import { randomPivotQuickSort } from "../random_pivot_quick_sort"; + +describe("Quick Sort Random Pivoting", () => { + it("should return the correct value for average case", () => { + expect(randomPivotQuickSort([1, 4, 2, 5, 9, 6, 3, 8, 10, 7])).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + }); + + it("should return the correct value for worst case", () => { + expect(randomPivotQuickSort([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + }); + + it("should return the correct value for best case", () => { + expect(randomPivotQuickSort([1, 4, 2, 9, 5, 7, 3, 8, 10, 6])).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + }); + }); \ No newline at end of file From 69a7cc36a084f67279eb93e0dad12eae5dd9b28b Mon Sep 17 00:00:00 2001 From: Ansh Tyagi Date: Sun, 1 Oct 2023 21:12:56 +0530 Subject: [PATCH 2/3] feat: add Random Pivot for Quick Sort --- sorts/quick_sort.ts | 18 +++++- sorts/random_pivot_quick_sort.ts | 74 ---------------------- sorts/test/random_pivot_quick_sort.test.ts | 15 ----- 3 files changed, 16 insertions(+), 91 deletions(-) delete mode 100644 sorts/random_pivot_quick_sort.ts delete mode 100644 sorts/test/random_pivot_quick_sort.test.ts diff --git a/sorts/quick_sort.ts b/sorts/quick_sort.ts index c0fd192e..beb900a4 100644 --- a/sorts/quick_sort.ts +++ b/sorts/quick_sort.ts @@ -10,7 +10,7 @@ export const partition = ( left: number = 0, right: number = array.length - 1 ) => { - const pivot = array[Math.floor((right + left) / 2)]; + const pivot = array[choosePivot(left,right)]; let i = left; let j = right; @@ -33,6 +33,20 @@ export const partition = ( return i; }; +/** + * @function choosePivot + * @description Chooses a pivot element randomly within the subarray. + * @param {number} left - The left index of the subarray. + * @param {number} right - The right index of the subarray. + * @returns {number} - The index of the chosen pivot element. + */ +export const choosePivot = ( + left: number, + right: number +): number => { + return Math.floor(Math.random() * (right - left + 1)) + left +}; + /** * Quicksort implementation * @@ -55,7 +69,7 @@ export const QuickSort = ( array: number[], left: number = 0, right: number = array.length - 1 -) => { +): number[] => { let index; if (array.length > 1) { diff --git a/sorts/random_pivot_quick_sort.ts b/sorts/random_pivot_quick_sort.ts deleted file mode 100644 index 08c11c4c..00000000 --- a/sorts/random_pivot_quick_sort.ts +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @function partition - * @description Partitions an array by selecting a random pivot element. - * @param {number[]} array - The array to partition. - * @param {number} left - The left index of the subarray. - * @param {number} right - The right index of the subarray. - * @returns {number} - The index of the pivot element after partitioning. - */ -export const partition = ( - array: number[], - left: number = 0, - right: number = array.length - 1 -): number => { - // Select a random pivot element within the subarray. - const randomPivot = array[Math.floor(Math.random() * (right - left + 1)) + left]; - let i = left; - let j = right; - - while (i <= j) { - while (array[i] < randomPivot) { - i++; - } - - while (array[j] > randomPivot) { - j--; - } - - if (i <= j) { - // Swap elements at indices i and j. - [array[i], array[j]] = [array[j], array[i]]; - i++; - j--; - } - } - - return i; -}; - -/** - * @function randomPivotQuickSort - * @description Sorts an array using the Quick Sort algorithm with random pivoting. - * @param {number[]} array - The array to sort. - * @param {number} left - The left index of the subarray. - * @param {number} right - The right index of the subarray. - * @returns {number[]} - The sorted array. - * @complexity_analysis - * Time complexity: - * - Best case: O(n log n) : Similar to the normal Quick Sort, the best case occurs when the pivot chosen in each step divides the array into roughly equal halves. - * - Average case: O(n log n) : This is also similar to the normal Quick Sort, but with a different constant factor due to random pivot selection. - * - Worst case: O(n^2) : The worst case can still be O(n^2) if, by random chance, the pivot selections repeatedly lead to unbalanced partitions. - * However, the worst-case scenario is less likely to occur in practice compared to the normal Quick Sort because of the random pivot selection. - * Space complexity: O(n log n) - */ -export const randomPivotQuickSort = ( - array: number[], - left: number = 0, - right: number = array.length - 1 -): number[] => { - let index; - - if (array.length > 1) { - index = partition(array, left, right); - - if (left < index - 1) { - randomPivotQuickSort(array, left, index - 1); - } - - if (index < right) { - randomPivotQuickSort(array, index, right); - } - } - - return array; -}; diff --git a/sorts/test/random_pivot_quick_sort.test.ts b/sorts/test/random_pivot_quick_sort.test.ts deleted file mode 100644 index b7f93a68..00000000 --- a/sorts/test/random_pivot_quick_sort.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { randomPivotQuickSort } from "../random_pivot_quick_sort"; - -describe("Quick Sort Random Pivoting", () => { - it("should return the correct value for average case", () => { - expect(randomPivotQuickSort([1, 4, 2, 5, 9, 6, 3, 8, 10, 7])).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - }); - - it("should return the correct value for worst case", () => { - expect(randomPivotQuickSort([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - }); - - it("should return the correct value for best case", () => { - expect(randomPivotQuickSort([1, 4, 2, 9, 5, 7, 3, 8, 10, 6])).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - }); - }); \ No newline at end of file From e821b6a93941b00f83508a1ca6fda516a01b4771 Mon Sep 17 00:00:00 2001 From: Ansh Tyagi Date: Sun, 1 Oct 2023 22:05:05 +0530 Subject: [PATCH 3/3] removed redundant export --- sorts/quick_sort.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorts/quick_sort.ts b/sorts/quick_sort.ts index beb900a4..a1abd5e8 100644 --- a/sorts/quick_sort.ts +++ b/sorts/quick_sort.ts @@ -40,7 +40,7 @@ export const partition = ( * @param {number} right - The right index of the subarray. * @returns {number} - The index of the chosen pivot element. */ -export const choosePivot = ( +const choosePivot = ( left: number, right: number ): number => {