From cdd12a128d061bd6a5cfae4e0d8d2478d24d1c47 Mon Sep 17 00:00:00 2001 From: Debasish Biswas Date: Sat, 15 Oct 2022 11:36:36 +0530 Subject: [PATCH] Add Dual Pivot QuickSort (#3357) --- .../sorts/DualPivotQuickSort.java | 111 ++++++++++++++++++ .../sorts/DualPivotQuickSortTest.java | 63 ++++++++++ 2 files changed, 174 insertions(+) create mode 100644 src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java create mode 100644 src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java diff --git a/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java b/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java new file mode 100644 index 000000000..9d6176c2d --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java @@ -0,0 +1,111 @@ +package com.thealgorithms.sorts; + +/** + * Dual Pivot Quick Sort Algorithm + * + * @author Debasish Biswas (https://github.com/debasishbsws) * + * @see SortAlgorithm + */ +public class DualPivotQuickSort implements SortAlgorithm { + + /** + * This method implements the Dual pivot Quick Sort + * + * @param array The array to be sorted Sorts the array in increasing order + */ + @Override + public > T[] sort(T[] array) { + dualPivotQuicksort(array, 0, array.length - 1); + return array; + } + + /** + * The sorting process + * + * @param left The first index of an array + * @param right The last index of an array + * @param array The array to be sorted + */ + private static > void dualPivotQuicksort(T[] array, int left, int right) { + if (left < right) { + int[] pivots = partition(array, left, right); + + dualPivotQuicksort(array, left, pivots[0] - 1); + dualPivotQuicksort(array, pivots[0] + 1, pivots[1] - 1); + dualPivotQuicksort(array, pivots[1] + 1, right); + } + } + + /** + * This method finds the partition indices for an array + * + * @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 + */ + private static > int[] partition(T[] array, int left, int right) { + if (array[left].compareTo(array[right]) > 0) + swap(array, left, right); + + T pivot1 = array[left]; + T pivot2 = array[right]; + + int j = left + 1; + int less = left + 1; + int great = right - 1; + + while (less <= great) { + // If element is less than pivot1 + if (array[less].compareTo(pivot1) < 0) { + 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--; + + swap(array, less, great--); + + if (array[less].compareTo(pivot1) < 0) + swap(array, less, left++); + + } + + less++; + } + j--; + great++; + // Bring the pivots to their appropriate positions + swap(array, left, j); + swap(array, right, great); + + // return the pivots' indices + return new int[] { less, great }; + } + + private static > void swap(T[] array, int left, int right) { + T temp = array[left]; + array[left] = array[right]; + array[right] = temp; + } + + /** + * 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/ + */ + +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java b/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java new file mode 100644 index 000000000..04a612ae9 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java @@ -0,0 +1,63 @@ +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); + } + +} \ No newline at end of file