diff --git a/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java b/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java index b02168f6..ada745ac 100644 --- a/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java +++ b/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java @@ -9,26 +9,33 @@ package com.thealgorithms.sorts; public class DualPivotQuickSort implements SortAlgorithm { /** - * This method implements the Dual pivot Quick Sort + * Sorts an array using the Dual Pivot QuickSort algorithm. * - * @param array The array to be sorted Sorts the array in increasing order + * @param array The array to be sorted + * @param The type of elements in the array, which must be comparable + * @return The sorted array */ @Override - public > T[] sort(T[] array) { + public > T[] sort(final T[] array) { + if (array.length <= 1) { + return array; + } + dualPivotQuicksort(array, 0, array.length - 1); return array; } /** - * The sorting process + * Recursively applies the Dual Pivot QuickSort algorithm to subarrays. * - * @param left The first index of an array - * @param right The last index of an array * @param array The array to be sorted + * @param left The starting index of the subarray + * @param right The ending index of the subarray + * @param The type of elements in the array, which must be comparable */ - private static > void dualPivotQuicksort(T[] array, int left, int right) { + private static > void dualPivotQuicksort(final T[] array, final int left, final int right) { if (left < right) { - int[] pivots = partition(array, left, right); + final int[] pivots = partition(array, left, right); dualPivotQuicksort(array, left, pivots[0] - 1); dualPivotQuicksort(array, pivots[0] + 1, pivots[1] - 1); @@ -37,70 +44,53 @@ public class DualPivotQuickSort implements SortAlgorithm { } /** - * This method finds the partition indices for an array + * Partitions the array into three parts using two pivots. * - * @param array The array to be sorted - * @param left The first index of an array - * @param right The last index of an array Finds the partition index of an array + * @param array The array to be partitioned + * @param left The starting index for partitioning + * @param right The ending index for partitioning + * @param The type of elements in the array, which must be comparable + * @return An array containing the indices of the two pivots */ - private static > int[] partition(T[] array, int left, int right) { - if (array[left].compareTo(array[right]) > 0) { + private static > int[] partition(final T[] array, int left, final int right) { + if (SortUtils.greater(array[left], array[right])) { SortUtils.swap(array, left, right); } - T pivot1 = array[left]; - T pivot2 = array[right]; + final T pivot1 = array[left]; + final T pivot2 = array[right]; - int j = left + 1; - int less = left + 1; - int great = right - 1; + int pivot1End = left + 1; + int low = left + 1; + int high = right - 1; - while (less <= great) { - // If element is less than pivot1 - if (array[less].compareTo(pivot1) < 0) { - SortUtils.swap(array, less, left++); - } - - // If element is greater or equal to pivot2 - else if (array[less].compareTo(pivot2) >= 0) { - while (less < great && array[great].compareTo(pivot2) > 0) { - great--; + while (low <= high) { + if (SortUtils.less(array[low], pivot1)) { + SortUtils.swap(array, low, pivot1End); + pivot1End++; + } else if (SortUtils.greaterOrEqual(array[low], pivot2)) { + while (low < high && SortUtils.greater(array[high], pivot2)) { + high--; } + SortUtils.swap(array, low, high); + high--; - SortUtils.swap(array, less, great--); - - if (array[less].compareTo(pivot1) < 0) { - SortUtils.swap(array, less, left++); + if (SortUtils.less(array[low], pivot1)) { + SortUtils.swap(array, low, pivot1End); + pivot1End++; } } - - less++; + low++; } - j--; - great++; - // Bring the pivots to their appropriate positions - SortUtils.swap(array, left, j); - SortUtils.swap(array, right, great); - // return the pivots' indices - return new int[] {less, great}; + // Place the pivots in their correct positions + pivot1End--; + high++; + + SortUtils.swap(array, left, pivot1End); + SortUtils.swap(array, right, high); + + // Return the indices of the pivots + return new int[] {low, high}; } - - /** - * Main method - * - * @param args the command line arguments - */ - public static void main(String[] args) { - Integer[] array = {24, 8, -42, 75, -29, -77, 38, 57}; - DualPivotQuickSort dualPivotQuickSort = new DualPivotQuickSort(); - dualPivotQuickSort.sort(array); - for (int i = 0; i < array.length; i++) { - System.out.print(array[i] + " "); - } - } - - /* - * References: https://www.geeksforgeeks.org/dual-pivot-quicksort/ - */ } diff --git a/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java b/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java index 112f3827..0b9cc1de 100644 --- a/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java @@ -1,62 +1,8 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - -import org.junit.jupiter.api.Test; - -/** - * @author Debasish Biswas (https://github.com/debasishbsws) - * @see DualPivotQuickSort - */ -class DualPivotQuickSortTest { - - private DualPivotQuickSort dualPivotquickSort = new DualPivotQuickSort(); - - @Test - void quickSortEmptyArrayShouldPass() { - Integer[] array = {}; - Integer[] sorted = dualPivotquickSort.sort(array); - Integer[] expected = {}; - assertArrayEquals(expected, sorted); - } - - @Test - void quickSortSingleValueArrayShouldPass() { - Integer[] array = {7}; - Integer[] sorted = dualPivotquickSort.sort(array); - Integer[] expected = {7}; - assertArrayEquals(expected, sorted); - } - - @Test - void quickSortWithIntegerArrayShouldPass() { - Integer[] array = {49, 4, 36, 9, 144, 1}; - Integer[] sorted = dualPivotquickSort.sort(array); - Integer[] expected = {1, 4, 9, 36, 49, 144}; - assertArrayEquals(expected, sorted); - } - - @Test - void quickSortForArrayWithNegativeValuesShouldPass() { - Integer[] array = {49, -36, -124, -49, 12, 9}; - Integer[] sorted = dualPivotquickSort.sort(array); - Integer[] expected = {-124, -49, -36, 9, 12, 49}; - assertArrayEquals(expected, sorted); - } - - @Test - void quickSortForArrayWithDuplicateValuesShouldPass() { - Integer[] array = {36, 1, 49, 1, 4, 9}; - Integer[] sorted = dualPivotquickSort.sort(array); - Integer[] expected = {1, 1, 4, 9, 36, 49}; - assertArrayEquals(expected, sorted); - } - - @Test - void quickSortWithStringArrayShouldPass() { - String[] array = {"cat", "ant", "eat", "boss", "dog", "apple"}; - String[] sorted = dualPivotquickSort.sort(array); - String[] expected = {"ant", "apple", "boss", "cat", "dog", "eat"}; - assertArrayEquals(expected, sorted); +class DualPivotQuickSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new DualPivotQuickSort(); } }