|
| 1 | +package org.trigon.utilities; |
| 2 | + |
| 3 | +import java.util.Arrays; |
| 4 | +import java.util.function.ToDoubleFunction; |
| 5 | + |
| 6 | +/** |
| 7 | + * A class that handles sorting of an array using <a href="https://en.wikipedia.org/wiki/Quicksort">Quick Sort</a>. |
| 8 | + * Quick Sort is a sorting method that partitions the array into smaller sections for faster sorting. |
| 9 | + * The sorting is done by selecting a pivot point and moving all values less than it to the left and all values greater than it to the right. |
| 10 | + * This is done recursively until the array is sorted. |
| 11 | + */ |
| 12 | +public class QuickSortHandler { |
| 13 | + /** |
| 14 | + * Uses quick sort to sort an array of objects by their double values. |
| 15 | + * Quick Sort is a sorting method that partitions the array into smaller sections for faster sorting. |
| 16 | + * The sorting is done by selecting a pivot point and moving all values less than it to the left and all values greater than it to the right. |
| 17 | + * This is done recursively until the array is sorted. |
| 18 | + * |
| 19 | + * @param array the array to sort |
| 20 | + * @param toDoubleFunction the function needed to convert an object in the array to a double |
| 21 | + */ |
| 22 | + public static <T> void sort(T[] array, ToDoubleFunction<T> toDoubleFunction) { |
| 23 | + quickSortByDoubleValue(array, toDoubleFunction, 0, array.length - 1); |
| 24 | + } |
| 25 | + |
| 26 | + /** |
| 27 | + * Runs a loop that partitions the given section of an array, sorts by their double value, and calculates a new pivot. |
| 28 | + * This method uses recursion and keeps calling itself until the array is sorted. |
| 29 | + * |
| 30 | + * @param array the array to sort |
| 31 | + * @param toDoubleFunction the function needed to convert an object in the array to a double |
| 32 | + * @param startIndex the index of the start of the unsorted section of the array |
| 33 | + * @param endIndex the index of the end of the unsorted section of the array |
| 34 | + */ |
| 35 | + private static <T> void quickSortByDoubleValue(T[] array, ToDoubleFunction<T> toDoubleFunction, int startIndex, int endIndex) { |
| 36 | + if (startIndex < endIndex) { |
| 37 | + final int pivot = partitionArrayAndGetNewPivot(array, toDoubleFunction, startIndex, endIndex); |
| 38 | + |
| 39 | + quickSortByDoubleValue(array, toDoubleFunction, startIndex, pivot - 1); |
| 40 | + quickSortByDoubleValue(array, toDoubleFunction, pivot + 1, endIndex); |
| 41 | + } |
| 42 | + } |
| 43 | + |
| 44 | + /** |
| 45 | + * Partitions the given section of an array by their double value and returns the new pivot. |
| 46 | + * |
| 47 | + * @param array the array to partition and sort |
| 48 | + * @param toDoubleFunction the function needed to convert an object in the array to a double |
| 49 | + * @param startIndex the start of the current partition of the array to partition |
| 50 | + * @param endIndex the end of the current partition of the array to partition |
| 51 | + * @return the index of the new pivot in the whole array |
| 52 | + */ |
| 53 | + private static <T> int partitionArrayAndGetNewPivot(T[] array, ToDoubleFunction<T> toDoubleFunction, int startIndex, int endIndex) { |
| 54 | + final double[] doubleArray = Arrays.stream(array).mapToDouble(toDoubleFunction).toArray(); |
| 55 | + final double pivot = doubleArray[endIndex]; |
| 56 | + |
| 57 | + int i = startIndex; |
| 58 | + for (int j = startIndex; j < endIndex; j++) { |
| 59 | + if (doubleArray[j] < pivot) { |
| 60 | + swapArrayValues(array, i, j); |
| 61 | + i++; |
| 62 | + } |
| 63 | + } |
| 64 | + swapArrayValues(array, i, endIndex); |
| 65 | + return i; |
| 66 | + } |
| 67 | + |
| 68 | + /** |
| 69 | + * Swaps the values held by two indices in an array. |
| 70 | + * |
| 71 | + * @param array the array to swap values in |
| 72 | + * @param firstIndex the index of the first value to swap |
| 73 | + * @param secondIndex the index of the second value to swap |
| 74 | + */ |
| 75 | + private static <T> void swapArrayValues(T[] array, int firstIndex, int secondIndex) { |
| 76 | + final T temp = array[firstIndex]; |
| 77 | + array[firstIndex] = array[secondIndex]; |
| 78 | + array[secondIndex] = temp; |
| 79 | + } |
| 80 | +} |
0 commit comments