refactor: cleanup DualPivotQuickSort
(#5319)
This commit is contained in:
parent
41f76e0e89
commit
8d0dd3ef32
@ -9,26 +9,33 @@ package com.thealgorithms.sorts;
|
|||||||
public class DualPivotQuickSort implements SortAlgorithm {
|
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 <T> The type of elements in the array, which must be comparable
|
||||||
|
* @return The sorted array
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T extends Comparable<T>> T[] sort(T[] array) {
|
public <T extends Comparable<T>> T[] sort(final T[] array) {
|
||||||
|
if (array.length <= 1) {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
dualPivotQuicksort(array, 0, array.length - 1);
|
dualPivotQuicksort(array, 0, array.length - 1);
|
||||||
return array;
|
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 array The array to be sorted
|
||||||
|
* @param left The starting index of the subarray
|
||||||
|
* @param right The ending index of the subarray
|
||||||
|
* @param <T> The type of elements in the array, which must be comparable
|
||||||
*/
|
*/
|
||||||
private static <T extends Comparable<T>> void dualPivotQuicksort(T[] array, int left, int right) {
|
private static <T extends Comparable<T>> void dualPivotQuicksort(final T[] array, final int left, final int right) {
|
||||||
if (left < 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, left, pivots[0] - 1);
|
||||||
dualPivotQuicksort(array, pivots[0] + 1, pivots[1] - 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 array The array to be partitioned
|
||||||
* @param left The first index of an array
|
* @param left The starting index for partitioning
|
||||||
* @param right The last index of an array Finds the partition index of an array
|
* @param right The ending index for partitioning
|
||||||
|
* @param <T> The type of elements in the array, which must be comparable
|
||||||
|
* @return An array containing the indices of the two pivots
|
||||||
*/
|
*/
|
||||||
private static <T extends Comparable<T>> int[] partition(T[] array, int left, int right) {
|
private static <T extends Comparable<T>> int[] partition(final T[] array, int left, final int right) {
|
||||||
if (array[left].compareTo(array[right]) > 0) {
|
if (SortUtils.greater(array[left], array[right])) {
|
||||||
SortUtils.swap(array, left, right);
|
SortUtils.swap(array, left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
T pivot1 = array[left];
|
final T pivot1 = array[left];
|
||||||
T pivot2 = array[right];
|
final T pivot2 = array[right];
|
||||||
|
|
||||||
int j = left + 1;
|
int pivot1End = left + 1;
|
||||||
int less = left + 1;
|
int low = left + 1;
|
||||||
int great = right - 1;
|
int high = right - 1;
|
||||||
|
|
||||||
while (less <= great) {
|
while (low <= high) {
|
||||||
// If element is less than pivot1
|
if (SortUtils.less(array[low], pivot1)) {
|
||||||
if (array[less].compareTo(pivot1) < 0) {
|
SortUtils.swap(array, low, pivot1End);
|
||||||
SortUtils.swap(array, less, left++);
|
pivot1End++;
|
||||||
|
} else if (SortUtils.greaterOrEqual(array[low], pivot2)) {
|
||||||
|
while (low < high && SortUtils.greater(array[high], pivot2)) {
|
||||||
|
high--;
|
||||||
}
|
}
|
||||||
|
SortUtils.swap(array, low, high);
|
||||||
|
high--;
|
||||||
|
|
||||||
// If element is greater or equal to pivot2
|
if (SortUtils.less(array[low], pivot1)) {
|
||||||
else if (array[less].compareTo(pivot2) >= 0) {
|
SortUtils.swap(array, low, pivot1End);
|
||||||
while (less < great && array[great].compareTo(pivot2) > 0) {
|
pivot1End++;
|
||||||
great--;
|
|
||||||
}
|
|
||||||
|
|
||||||
SortUtils.swap(array, less, great--);
|
|
||||||
|
|
||||||
if (array[less].compareTo(pivot1) < 0) {
|
|
||||||
SortUtils.swap(array, less, left++);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
low++;
|
||||||
less++;
|
|
||||||
}
|
|
||||||
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
|
||||||
* Main method
|
pivot1End--;
|
||||||
*
|
high++;
|
||||||
* @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] + " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
SortUtils.swap(array, left, pivot1End);
|
||||||
* References: https://www.geeksforgeeks.org/dual-pivot-quicksort/
|
SortUtils.swap(array, right, high);
|
||||||
*/
|
|
||||||
|
// Return the indices of the pivots
|
||||||
|
return new int[] {low, high};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,62 +1,8 @@
|
|||||||
package com.thealgorithms.sorts;
|
package com.thealgorithms.sorts;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
class DualPivotQuickSortTest extends SortingAlgorithmTest {
|
||||||
|
@Override
|
||||||
import org.junit.jupiter.api.Test;
|
SortAlgorithm getSortAlgorithm() {
|
||||||
|
return new DualPivotQuickSort();
|
||||||
/**
|
|
||||||
* @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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user