diff --git a/src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java b/src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java index 2c71bae8b557..8d2b6c59f864 100644 --- a/src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java +++ b/src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java @@ -1,40 +1,40 @@ package com.thealgorithms.sorts; public class AdaptiveMergeSort implements SortAlgorithm { - @SuppressWarnings("unchecked") - public > T[] sort(T[] array) { - if (array.length <= 1) { - return array; - } - T[] aux = array.clone(); - sort(array, aux, 0, array.length - 1); - return array; - } + @SuppressWarnings("unchecked") + public > T[] sort(T[] array) { + if (array.length <= 1) { + return array; + } + T[] aux = array.clone(); + sort(array, aux, 0, array.length - 1); + return array; + } - private > void sort(T[] array, T[] aux, int low, int high) { - if (low >= high) { - return; - } - int mid = low + (high - low) / 2; - sort(array, aux, low, mid); - sort(array, aux, mid + 1, high); - merge(array, aux, low, mid, high); - } + private > void sort(T[] array, T[] aux, int low, int high) { + if (low >= high) { + return; + } + int mid = low + (high - low) / 2; + sort(array, aux, low, mid); + sort(array, aux, mid + 1, high); + merge(array, aux, low, mid, high); + } - private > void merge(T[] array, T[] aux, int low, int mid, int high) { - System.arraycopy(array, low, aux, low, high - low + 1); - int i = low; - int j = mid + 1; - for (int k = low; k <= high; k++) { - if (i > mid) { - array[k] = aux[j++]; - } else if (j > high) { - array[k] = aux[i++]; - } else if (aux[j].compareTo(aux[i]) < 0) { - array[k] = aux[j++]; - } else { - array[k] = aux[i++]; - } - } - } + private > void merge(T[] array, T[] aux, int low, int mid, int high) { + System.arraycopy(array, low, aux, low, high - low + 1); + int i = low; + int j = mid + 1; + for (int k = low; k <= high; k++) { + if (i > mid) { + array[k] = aux[j++]; + } else if (j > high) { + array[k] = aux[i++]; + } else if (SortUtils.less(aux[j], aux[i])) { + array[k] = aux[j++]; + } else { + array[k] = aux[i++]; + } + } + } } diff --git a/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java b/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java index b6f5d92e7928..b8086bd0ebca 100644 --- a/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java +++ b/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java @@ -22,7 +22,7 @@ public > T[] sort(T[] array) { while (low <= high) { final int mid = (low + high) >>> 1; - if (temp.compareTo(array[mid]) < 0) { + if (SortUtils.less(temp, array[mid])) { high = mid - 1; } else { low = mid + 1; diff --git a/src/main/java/com/thealgorithms/sorts/BitonicSort.java b/src/main/java/com/thealgorithms/sorts/BitonicSort.java index 90d204818729..f93171736e19 100644 --- a/src/main/java/com/thealgorithms/sorts/BitonicSort.java +++ b/src/main/java/com/thealgorithms/sorts/BitonicSort.java @@ -4,109 +4,113 @@ import java.util.function.BiPredicate; /** - * BitonicSort class implements the SortAlgorithm interface using the bitonic sort technique. + * BitonicSort class implements the SortAlgorithm interface using the bitonic + * sort technique. */ public class BitonicSort implements SortAlgorithm { - private enum Direction { - DESCENDING, - ASCENDING, - } - - /** - * Sorts the given array using the Bitonic Sort algorithm. - * - * @param the type of elements in the array, which must implement the Comparable interface - * @param array the array to be sorted - * @return the sorted array - */ - @Override - public > T[] sort(T[] array) { - if (array.length == 0) { - return array; - } - - final int paddedSize = nextPowerOfTwo(array.length); - T[] paddedArray = Arrays.copyOf(array, paddedSize); - - // Fill the padded part with a maximum value - final T maxValue = max(array); - Arrays.fill(paddedArray, array.length, paddedSize, maxValue); - - bitonicSort(paddedArray, 0, paddedSize, Direction.ASCENDING); - return Arrays.copyOf(paddedArray, array.length); - } - - private > void bitonicSort(final T[] array, final int low, final int cnt, final Direction direction) { - if (cnt > 1) { - final int k = cnt / 2; - - // Sort first half in ascending order - bitonicSort(array, low, k, Direction.ASCENDING); - - // Sort second half in descending order - bitonicSort(array, low + k, cnt - k, Direction.DESCENDING); - - // Merge the whole sequence in ascending order - bitonicMerge(array, low, cnt, direction); - } - } - - /** - * Merges the bitonic sequence in the specified direction. - * - * @param the type of elements in the array, which must be Comparable - * @param array the array containing the bitonic sequence to be merged - * @param low the starting index of the sequence to be merged - * @param cnt the number of elements in the sequence to be merged - * @param direction the direction of sorting - */ - private > void bitonicMerge(T[] array, int low, int cnt, Direction direction) { - if (cnt > 1) { - final int k = cnt / 2; - - final BiPredicate areSorted = (direction == Direction.ASCENDING) ? (a, b) -> a.compareTo(b) < 0 : (a, b) -> a.compareTo(b) > 0; - for (int i = low; i < low + k; i++) { - if (!areSorted.test(array[i], array[i + k])) { - SortUtils.swap(array, i, i + k); - } - } - - bitonicMerge(array, low, k, direction); - bitonicMerge(array, low + k, cnt - k, direction); - } - } - - /** - * Finds the next power of two greater than or equal to the given number. - * - * @param n the number - * @return the next power of two - */ - private static int nextPowerOfTwo(int n) { - int count = 0; - - // First n in the below condition is for the case where n is 0 - if ((n & (n - 1)) == 0) { - return n; - } - - while (n != 0) { - n >>= 1; - count += 1; - } - - return 1 << count; - } - - /** - * Finds the maximum element in the given array. - * - * @param the type of elements in the array, which must implement the Comparable interface - * @param array the array to be searched - * @return the maximum element in the array - * @throws IllegalArgumentException if the array is null or empty - */ - private static > T max(final T[] array) { - return Arrays.stream(array).max(Comparable::compareTo).orElseThrow(); - } + private enum Direction { + DESCENDING, ASCENDING, + } + + /** + * Sorts the given array using the Bitonic Sort algorithm. + * + * @param the type of elements in the array, which must implement the + * Comparable interface + * @param array the array to be sorted + * @return the sorted array + */ + @Override + public > T[] sort(T[] array) { + if (array.length == 0) { + return array; + } + + final int paddedSize = nextPowerOfTwo(array.length); + T[] paddedArray = Arrays.copyOf(array, paddedSize); + + // Fill the padded part with a maximum value + final T maxValue = max(array); + Arrays.fill(paddedArray, array.length, paddedSize, maxValue); + + bitonicSort(paddedArray, 0, paddedSize, Direction.ASCENDING); + return Arrays.copyOf(paddedArray, array.length); + } + + private > void bitonicSort(final T[] array, final int low, final int cnt, + final Direction direction) { + if (cnt > 1) { + final int k = cnt / 2; + + // Sort first half in ascending order + bitonicSort(array, low, k, Direction.ASCENDING); + + // Sort second half in descending order + bitonicSort(array, low + k, cnt - k, Direction.DESCENDING); + + // Merge the whole sequence in ascending order + bitonicMerge(array, low, cnt, direction); + } + } + + /** + * Merges the bitonic sequence in the specified direction. + * + * @param the type of elements in the array, which must be Comparable + * @param array the array containing the bitonic sequence to be merged + * @param low the starting index of the sequence to be merged + * @param cnt the number of elements in the sequence to be merged + * @param direction the direction of sorting + */ + private > void bitonicMerge(T[] array, int low, int cnt, Direction direction) { + if (cnt > 1) { + final int k = cnt / 2; + + final BiPredicate areSorted = (direction == Direction.ASCENDING) ? (a, b) -> SortUtils.less(a, b) + : (a, b) -> SortUtils.greater(a, b); + for (int i = low; i < low + k; i++) { + if (!areSorted.test(array[i], array[i + k])) { + SortUtils.swap(array, i, i + k); + } + } + + bitonicMerge(array, low, k, direction); + bitonicMerge(array, low + k, cnt - k, direction); + } + } + + /** + * Finds the next power of two greater than or equal to the given number. + * + * @param n the number + * @return the next power of two + */ + private static int nextPowerOfTwo(int n) { + int count = 0; + + // First n in the below condition is for the case where n is 0 + if ((n & (n - 1)) == 0) { + return n; + } + + while (n != 0) { + n >>= 1; + count += 1; + } + + return 1 << count; + } + + /** + * Finds the maximum element in the given array. + * + * @param the type of elements in the array, which must implement the + * Comparable interface + * @param array the array to be searched + * @return the maximum element in the array + * @throws IllegalArgumentException if the array is null or empty + */ + private static > T max(final T[] array) { + return Arrays.stream(array).max(Comparable::compareTo).orElseThrow(); + } } diff --git a/src/main/java/com/thealgorithms/sorts/BucketSort.java b/src/main/java/com/thealgorithms/sorts/BucketSort.java index 62c5e929593b..948192ed05f2 100644 --- a/src/main/java/com/thealgorithms/sorts/BucketSort.java +++ b/src/main/java/com/thealgorithms/sorts/BucketSort.java @@ -5,126 +5,128 @@ import java.util.List; /** - * BucketSort class provides a method to sort an array of elements using the Bucket Sort algorithm - * and implements the SortAlgorithm interface. + * BucketSort class provides a method to sort an array of elements using the + * Bucket Sort algorithm and implements the SortAlgorithm interface. */ public class BucketSort implements SortAlgorithm { - // Constant that defines the divisor for determining the number of buckets - private static final int BUCKET_DIVISOR = 10; + // Constant that defines the divisor for determining the number of buckets + private static final int BUCKET_DIVISOR = 10; - @Override - public > T[] sort(T[] array) { - if (array.length == 0) { - return array; - } + @Override + public > T[] sort(T[] array) { + if (array.length == 0) { + return array; + } - T min = findMin(array); - T max = findMax(array); - int numberOfBuckets = calculateNumberOfBuckets(array.length); + T min = findMin(array); + T max = findMax(array); + int numberOfBuckets = calculateNumberOfBuckets(array.length); - List> buckets = initializeBuckets(numberOfBuckets); - distributeElementsIntoBuckets(array, buckets, min, max, numberOfBuckets); + List> buckets = initializeBuckets(numberOfBuckets); + distributeElementsIntoBuckets(array, buckets, min, max, numberOfBuckets); - return concatenateBuckets(buckets, array); - } + return concatenateBuckets(buckets, array); + } - /** - * Calculates the number of buckets to use based on the size of the array. - * - * @param arrayLength the length of the array - * @return the number of buckets - */ - private int calculateNumberOfBuckets(final int arrayLength) { - return Math.max(arrayLength / BUCKET_DIVISOR, 1); - } + /** + * Calculates the number of buckets to use based on the size of the array. + * + * @param arrayLength the length of the array + * @return the number of buckets + */ + private int calculateNumberOfBuckets(final int arrayLength) { + return Math.max(arrayLength / BUCKET_DIVISOR, 1); + } - /** - * Initializes a list of empty buckets. - * - * @param numberOfBuckets the number of buckets to initialize - * @param the type of elements to be sorted - * @return a list of empty buckets - */ - private > List> initializeBuckets(int numberOfBuckets) { - List> buckets = new ArrayList<>(numberOfBuckets); - for (int i = 0; i < numberOfBuckets; i++) { - buckets.add(new ArrayList<>()); - } - return buckets; - } + /** + * Initializes a list of empty buckets. + * + * @param numberOfBuckets the number of buckets to initialize + * @param the type of elements to be sorted + * @return a list of empty buckets + */ + private > List> initializeBuckets(int numberOfBuckets) { + List> buckets = new ArrayList<>(numberOfBuckets); + for (int i = 0; i < numberOfBuckets; i++) { + buckets.add(new ArrayList<>()); + } + return buckets; + } - /** - * Distributes elements from the array into the appropriate buckets. - * - * @param array the array of elements to distribute - * @param buckets the list of buckets - * @param min the minimum value in the array - * @param max the maximum value in the array - * @param numberOfBuckets the total number of buckets - * @param the type of elements in the array - */ - private > void distributeElementsIntoBuckets(T[] array, List> buckets, final T min, final T max, final int numberOfBuckets) { - for (final T element : array) { - int bucketIndex = hash(element, min, max, numberOfBuckets); - buckets.get(bucketIndex).add(element); - } - } + /** + * Distributes elements from the array into the appropriate buckets. + * + * @param array the array of elements to distribute + * @param buckets the list of buckets + * @param min the minimum value in the array + * @param max the maximum value in the array + * @param numberOfBuckets the total number of buckets + * @param the type of elements in the array + */ + private > void distributeElementsIntoBuckets(T[] array, List> buckets, final T min, + final T max, final int numberOfBuckets) { + for (final T element : array) { + int bucketIndex = hash(element, min, max, numberOfBuckets); + buckets.get(bucketIndex).add(element); + } + } - /** - * Concatenates the sorted buckets back into the original array. - * - * @param buckets the list of sorted buckets - * @param array the original array - * @param the type of elements in the array - * @return the sorted array - */ - private > T[] concatenateBuckets(Iterable> buckets, T[] array) { - int index = 0; - for (List bucket : buckets) { - Collections.sort(bucket); - for (T element : bucket) { - array[index++] = element; - } - } - return array; - } + /** + * Concatenates the sorted buckets back into the original array. + * + * @param buckets the list of sorted buckets + * @param array the original array + * @param the type of elements in the array + * @return the sorted array + */ + private > T[] concatenateBuckets(Iterable> buckets, T[] array) { + int index = 0; + for (List bucket : buckets) { + Collections.sort(bucket); + for (T element : bucket) { + array[index++] = element; + } + } + return array; + } - /** - * The method computes the index of the bucket in which a given element should be placed. - * This is done by "normalizing" the element within the range of the array's minimum (min) and maximum (max) values, - * and then mapping this normalized value to a specific bucket index. - * - * @param element the element of the array - * @param min the minimum value in the array - * @param max the maximum value in the array - * @param numberOfBuckets the total number of buckets - * @param the type of elements in the array - * @return the index of the bucket - */ - private > int hash(final T element, final T min, final T max, final int numberOfBuckets) { - double range = max.compareTo(min); - double normalizedValue = element.compareTo(min) / range; - return (int) (normalizedValue * (numberOfBuckets - 1)); - } + /** + * The method computes the index of the bucket in which a given element should + * be placed. This is done by "normalizing" the element within the range of the + * array's minimum (min) and maximum (max) values, and then mapping this + * normalized value to a specific bucket index. + * + * @param element the element of the array + * @param min the minimum value in the array + * @param max the maximum value in the array + * @param numberOfBuckets the total number of buckets + * @param the type of elements in the array + * @return the index of the bucket + */ + private > int hash(final T element, final T min, final T max, final int numberOfBuckets) { + double range = max.compareTo(min); + double normalizedValue = element.compareTo(min) / range; + return (int) (normalizedValue * (numberOfBuckets - 1)); + } - private > T findMin(T[] array) { - T min = array[0]; - for (T element : array) { - if (element.compareTo(min) < 0) { - min = element; - } - } - return min; - } + private > T findMin(T[] array) { + T min = array[0]; + for (T element : array) { + if (SortUtils.less(element, min)) { + min = element; + } + } + return min; + } - private > T findMax(T[] array) { - T max = array[0]; - for (T element : array) { - if (element.compareTo(max) > 0) { - max = element; - } - } - return max; - } + private > T findMax(T[] array) { + T max = array[0]; + for (T element : array) { + if (SortUtils.greater(element, max)) { + max = element; + } + } + return max; + } } diff --git a/src/main/java/com/thealgorithms/sorts/CircleSort.java b/src/main/java/com/thealgorithms/sorts/CircleSort.java index b9b41be16701..335e1f11d80a 100644 --- a/src/main/java/com/thealgorithms/sorts/CircleSort.java +++ b/src/main/java/com/thealgorithms/sorts/CircleSort.java @@ -2,57 +2,59 @@ public class CircleSort implements SortAlgorithm { - /* This method implements the circle sort - * @param array The array to be sorted - */ - @Override - public > T[] sort(T[] array) { - if (array.length == 0) { - return array; - } - while (doSort(array, 0, array.length - 1)) { - } - return array; - } - - /** - * Recursively sorts the array in a circular manner by comparing elements - * from the start and end of the current segment. - * - * @param The type of elements in the array, which must be comparable - * @param array The array to be sorted - * @param left The left boundary of the current segment being sorted - * @param right The right boundary of the current segment being sorted - * @return true if any elements were swapped during the sort; false otherwise - */ - private > boolean doSort(final T[] array, final int left, final int right) { - boolean swapped = false; - - if (left == right) { - return false; - } - - int low = left; - int high = right; - - while (low < high) { - if (array[low].compareTo(array[high]) > 0) { - SortUtils.swap(array, low, high); - swapped = true; - } - low++; - high--; - } - - if (low == high && array[low].compareTo(array[high + 1]) > 0) { - SortUtils.swap(array, low, high + 1); - swapped = true; - } - - final int mid = left + (right - left) / 2; - final boolean leftHalfSwapped = doSort(array, left, mid); - final boolean rightHalfSwapped = doSort(array, mid + 1, right); - - return swapped || leftHalfSwapped || rightHalfSwapped; - } + /* + * This method implements the circle sort + * + * @param array The array to be sorted + */ + @Override + public > T[] sort(T[] array) { + if (array.length == 0) { + return array; + } + while (doSort(array, 0, array.length - 1)) { + } + return array; + } + + /** + * Recursively sorts the array in a circular manner by comparing elements from + * the start and end of the current segment. + * + * @param The type of elements in the array, which must be comparable + * @param array The array to be sorted + * @param left The left boundary of the current segment being sorted + * @param right The right boundary of the current segment being sorted + * @return true if any elements were swapped during the sort; false otherwise + */ + private > boolean doSort(final T[] array, final int left, final int right) { + boolean swapped = false; + + if (left == right) { + return false; + } + + int low = left; + int high = right; + + while (low < high) { + if (SortUtils.greater(array[low], array[high])) { + SortUtils.swap(array, low, high); + swapped = true; + } + low++; + high--; + } + + if (low == high && SortUtils.greater(array[low], array[high + 1])) { + SortUtils.swap(array, low, high + 1); + swapped = true; + } + + final int mid = left + (right - left) / 2; + final boolean leftHalfSwapped = doSort(array, left, mid); + final boolean rightHalfSwapped = doSort(array, mid + 1, right); + + return swapped || leftHalfSwapped || rightHalfSwapped; + } } diff --git a/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java b/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java index abfcb452b29a..62f5b84eeebb 100644 --- a/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java +++ b/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java @@ -1,42 +1,44 @@ package com.thealgorithms.sorts; /** - * The Dutch National Flag Sort sorts a sequence of values into three permutations which are defined - * by a value given as the indented middle. First permutation: values less than middle. Second - * permutation: values equal middle. Third permutation: values greater than middle. If no indented - * middle is given, this implementation will use a value from the given Array. This value is the one - * positioned in the arrays' middle if the arrays' length is odd. If the arrays' length is even, the - * value left to the middle will be used. More information and Pseudocode: + * The Dutch National Flag Sort sorts a sequence of values into three + * permutations which are defined by a value given as the indented middle. First + * permutation: values less than middle. Second permutation: values equal + * middle. Third permutation: values greater than middle. If no indented middle + * is given, this implementation will use a value from the given Array. This + * value is the one positioned in the arrays' middle if the arrays' length is + * odd. If the arrays' length is even, the value left to the middle will be + * used. More information and Pseudocode: * https://en.wikipedia.org/wiki/Dutch_national_flag_problem */ public class DutchNationalFlagSort implements SortAlgorithm { - @Override - public > T[] sort(T[] array) { - return dutchNationalFlagSort(array, array[(int) Math.ceil((array.length) / 2.0) - 1]); - } + @Override + public > T[] sort(T[] array) { + return dutchNationalFlagSort(array, array[(int) Math.ceil((array.length) / 2.0) - 1]); + } - public > T[] sort(T[] array, T intendedMiddle) { - return dutchNationalFlagSort(array, intendedMiddle); - } + public > T[] sort(T[] array, T intendedMiddle) { + return dutchNationalFlagSort(array, intendedMiddle); + } - private > T[] dutchNationalFlagSort(final T[] array, final T intendedMiddle) { - int i = 0; - int j = 0; - int k = array.length - 1; + private > T[] dutchNationalFlagSort(final T[] array, final T intendedMiddle) { + int i = 0; + int j = 0; + int k = array.length - 1; - while (j <= k) { - if (0 > array[j].compareTo(intendedMiddle)) { - SortUtils.swap(array, i, j); - j++; - i++; - } else if (0 < array[j].compareTo(intendedMiddle)) { - SortUtils.swap(array, j, k); - k--; - } else { - j++; - } - } - return array; - } + while (j <= k) { + if (SortUtils.less(array[j], intendedMiddle)) { + SortUtils.swap(array, i, j); + j++; + i++; + } else if (SortUtils.greater(array[j], intendedMiddle)) { + SortUtils.swap(array, j, k); + k--; + } else { + j++; + } + } + return array; + } } diff --git a/src/main/java/com/thealgorithms/sorts/ExchangeSort.java b/src/main/java/com/thealgorithms/sorts/ExchangeSort.java index 67e94b889671..75af42bbe28d 100644 --- a/src/main/java/com/thealgorithms/sorts/ExchangeSort.java +++ b/src/main/java/com/thealgorithms/sorts/ExchangeSort.java @@ -5,12 +5,12 @@ * *

* Exchange sort works by comparing each element with all subsequent elements, - * swapping where needed, to ensure the correct placement of each element - * in the final sorted order. It iteratively performs this process for each - * element in the array. While it lacks the advantage of bubble sort in - * detecting sorted lists in one pass, it can be more efficient than bubble sort - * due to a constant factor (one less pass over the data to be sorted; half as - * many total comparisons) in worst-case scenarios. + * swapping where needed, to ensure the correct placement of each element in the + * final sorted order. It iteratively performs this process for each element in + * the array. While it lacks the advantage of bubble sort in detecting sorted + * lists in one pass, it can be more efficient than bubble sort due to a + * constant factor (one less pass over the data to be sorted; half as many total + * comparisons) in worst-case scenarios. *

* *

@@ -20,22 +20,22 @@ * @author 555vedant (Vedant Kasar) */ class ExchangeSort implements SortAlgorithm { - /** - * Implementation of Exchange Sort Algorithm - * - * @param array the array to be sorted. - * @param the type of elements in the array. - * @return the sorted array. - */ - @Override - public > T[] sort(T[] array) { - for (int i = 0; i < array.length - 1; i++) { - for (int j = i + 1; j < array.length; j++) { - if (array[i].compareTo(array[j]) > 0) { - SortUtils.swap(array, i, j); - } - } - } - return array; - } + /** + * Implementation of Exchange Sort Algorithm + * + * @param array the array to be sorted. + * @param the type of elements in the array. + * @return the sorted array. + */ + @Override + public > T[] sort(T[] array) { + for (int i = 0; i < array.length - 1; i++) { + for (int j = i + 1; j < array.length; j++) { + if (SortUtils.greater(array[i], array[j])) { + SortUtils.swap(array, i, j); + } + } + } + return array; + } } diff --git a/src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java b/src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java index 12ef197b931b..67001d2ea51e 100644 --- a/src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java +++ b/src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java @@ -3,137 +3,140 @@ /** * Introspective Sort Algorithm Implementation * - * @see IntroSort Algorithm + * @see IntroSort + * Algorithm */ public class IntrospectiveSort implements SortAlgorithm { - private static final int INSERTION_SORT_THRESHOLD = 16; + private static final int INSERTION_SORT_THRESHOLD = 16; - /** - * Sorts the given array using Introspective Sort, which combines quicksort, heapsort, and insertion sort. - * - * @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) { - if (array == null || array.length <= 1) { - return array; - } - final int depth = 2 * (int) (Math.log(array.length) / Math.log(2)); - introspectiveSort(array, 0, array.length - 1, depth); - return array; - } + /** + * Sorts the given array using Introspective Sort, which combines quicksort, + * heapsort, and insertion sort. + * + * @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) { + if (array == null || array.length <= 1) { + return array; + } + final int depth = 2 * (int) (Math.log(array.length) / Math.log(2)); + introspectiveSort(array, 0, array.length - 1, depth); + return array; + } - /** - * Performs introspective sort on the specified subarray. - * - * @param array The array to be sorted - * @param low The starting index of the subarray - * @param high The ending index of the subarray - * @param depth The current depth of recursion - * @param The type of elements in the array, which must be comparable - */ - private static > void introspectiveSort(T[] array, final int low, int high, final int depth) { - while (high - low > INSERTION_SORT_THRESHOLD) { - if (depth == 0) { - heapSort(array, low, high); - return; - } - final int pivotIndex = partition(array, low, high); - introspectiveSort(array, pivotIndex + 1, high, depth - 1); - high = pivotIndex - 1; - } - insertionSort(array, low, high); - } + /** + * Performs introspective sort on the specified subarray. + * + * @param array The array to be sorted + * @param low The starting index of the subarray + * @param high The ending index of the subarray + * @param depth The current depth of recursion + * @param The type of elements in the array, which must be comparable + */ + private static > void introspectiveSort(T[] array, final int low, int high, + final int depth) { + while (high - low > INSERTION_SORT_THRESHOLD) { + if (depth == 0) { + heapSort(array, low, high); + return; + } + final int pivotIndex = partition(array, low, high); + introspectiveSort(array, pivotIndex + 1, high, depth - 1); + high = pivotIndex - 1; + } + insertionSort(array, low, high); + } - /** - * Partitions the array around a pivot. - * - * @param array The array to be partitioned - * @param low The starting index of the subarray - * @param high The ending index of the subarray - * @param The type of elements in the array, which must be comparable - * @return The index of the pivot - */ - private static > int partition(T[] array, final int low, final int high) { - final int pivotIndex = low + (int) (Math.random() * (high - low + 1)); - SortUtils.swap(array, pivotIndex, high); - final T pivot = array[high]; - int i = low - 1; - for (int j = low; j < high; j++) { - if (array[j].compareTo(pivot) <= 0) { - i++; - SortUtils.swap(array, i, j); - } - } - SortUtils.swap(array, i + 1, high); - return i + 1; - } + /** + * Partitions the array around a pivot. + * + * @param array The array to be partitioned + * @param low The starting index of the subarray + * @param high The ending index of the subarray + * @param The type of elements in the array, which must be comparable + * @return The index of the pivot + */ + private static > int partition(T[] array, final int low, final int high) { + final int pivotIndex = low + (int) (Math.random() * (high - low + 1)); + SortUtils.swap(array, pivotIndex, high); + final T pivot = array[high]; + int i = low - 1; + for (int j = low; j < high; j++) { + if (SortUtils.greaterOrEqual(pivot, array[j])) { + i++; + SortUtils.swap(array, i, j); + } + } + SortUtils.swap(array, i + 1, high); + return i + 1; + } - /** - * Sorts a subarray using insertion sort. - * - * @param array The array to be sorted - * @param low The starting index of the subarray - * @param high The ending index of the subarray - * @param The type of elements in the array, which must be comparable - */ - private static > void insertionSort(T[] array, final int low, final int high) { - for (int i = low + 1; i <= high; i++) { - final T key = array[i]; - int j = i - 1; - while (j >= low && array[j].compareTo(key) > 0) { - array[j + 1] = array[j]; - j--; - } - array[j + 1] = key; - } - } + /** + * Sorts a subarray using insertion sort. + * + * @param array The array to be sorted + * @param low The starting index of the subarray + * @param high The ending index of the subarray + * @param The type of elements in the array, which must be comparable + */ + private static > void insertionSort(T[] array, final int low, final int high) { + for (int i = low + 1; i <= high; i++) { + final T key = array[i]; + int j = i - 1; + while (j >= low && SortUtils.greater(array[j], key)) { + array[j + 1] = array[j]; + j--; + } + array[j + 1] = key; + } + } - /** - * Sorts a subarray using heapsort. - * - * @param array The array to be sorted - * @param low The starting index of the subarray - * @param high The ending index of the subarray - * @param The type of elements in the array, which must be comparable - */ - private static > void heapSort(T[] array, final int low, final int high) { - final int n = high - low + 1; - for (int i = (n / 2) - 1; i >= 0; i--) { - heapify(array, i, n, low); - } - for (int i = high; i > low; i--) { - SortUtils.swap(array, low, i); - heapify(array, 0, i - low, low); - } - } + /** + * Sorts a subarray using heapsort. + * + * @param array The array to be sorted + * @param low The starting index of the subarray + * @param high The ending index of the subarray + * @param The type of elements in the array, which must be comparable + */ + private static > void heapSort(T[] array, final int low, final int high) { + final int n = high - low + 1; + for (int i = (n / 2) - 1; i >= 0; i--) { + heapify(array, i, n, low); + } + for (int i = high; i > low; i--) { + SortUtils.swap(array, low, i); + heapify(array, 0, i - low, low); + } + } - /** - * Maintains the heap property for a subarray. - * - * @param array The array to be heapified - * @param i The index to be heapified - * @param n The size of the heap - * @param low The starting index of the subarray - * @param The type of elements in the array, which must be comparable - */ - private static > void heapify(T[] array, final int i, final int n, final int low) { - final int left = 2 * i + 1; - final int right = 2 * i + 2; - int largest = i; + /** + * Maintains the heap property for a subarray. + * + * @param array The array to be heapified + * @param i The index to be heapified + * @param n The size of the heap + * @param low The starting index of the subarray + * @param The type of elements in the array, which must be comparable + */ + private static > void heapify(T[] array, final int i, final int n, final int low) { + final int left = 2 * i + 1; + final int right = 2 * i + 2; + int largest = i; - if (left < n && array[low + left].compareTo(array[low + largest]) > 0) { - largest = left; - } - if (right < n && array[low + right].compareTo(array[low + largest]) > 0) { - largest = right; - } - if (largest != i) { - SortUtils.swap(array, low + i, low + largest); - heapify(array, largest, n, low); - } - } + if (left < n && SortUtils.greater(array[low + left], array[low + largest])) { + largest = left; + } + if (right < n && SortUtils.greater(array[low + left], array[low + largest])) { + largest = right; + } + if (largest != i) { + SortUtils.swap(array, low + i, low + largest); + heapify(array, largest, n, low); + } + } } diff --git a/src/main/java/com/thealgorithms/sorts/OddEvenSort.java b/src/main/java/com/thealgorithms/sorts/OddEvenSort.java index ac94982c1474..8f62f1792fe2 100644 --- a/src/main/java/com/thealgorithms/sorts/OddEvenSort.java +++ b/src/main/java/com/thealgorithms/sorts/OddEvenSort.java @@ -1,51 +1,54 @@ package com.thealgorithms.sorts; /** - * OddEvenSort class implements the SortAlgorithm interface using the odd-even sort technique. - * Odd-even sort is a comparison sort related to bubble sort. - * It operates by comparing all (odd, even)-indexed pairs of adjacent elements in the list and, if a pair is in the wrong order, swapping them. - * The next step repeats this process for (even, odd)-indexed pairs. This process continues until the list is sorted. + * OddEvenSort class implements the SortAlgorithm interface using the odd-even + * sort technique. Odd-even sort is a comparison sort related to bubble sort. It + * operates by comparing all (odd, even)-indexed pairs of adjacent elements in + * the list and, if a pair is in the wrong order, swapping them. The next step + * repeats this process for (even, odd)-indexed pairs. This process continues + * until the list is sorted. * */ public final class OddEvenSort implements SortAlgorithm { - /** - * Sorts the given array using the Odd-Even Sort algorithm. - * - * @param the type of elements in the array, which must implement the Comparable interface - * @param array the array to be sorted - * @return the sorted array - */ - @Override - public > T[] sort(T[] array) { - boolean sorted = false; - while (!sorted) { - sorted = performOddSort(array); - sorted = performEvenSort(array) && sorted; - } + /** + * Sorts the given array using the Odd-Even Sort algorithm. + * + * @param the type of elements in the array, which must implement the + * Comparable interface + * @param array the array to be sorted + * @return the sorted array + */ + @Override + public > T[] sort(T[] array) { + boolean sorted = false; + while (!sorted) { + sorted = performOddSort(array); + sorted = performEvenSort(array) && sorted; + } - return array; - } + return array; + } - private > boolean performOddSort(T[] array) { - boolean sorted = true; - for (int i = 1; i < array.length - 1; i += 2) { - if (array[i].compareTo(array[i + 1]) > 0) { - SortUtils.swap(array, i, i + 1); - sorted = false; - } - } - return sorted; - } + private > boolean performOddSort(T[] array) { + boolean sorted = true; + for (int i = 1; i < array.length - 1; i += 2) { + if (SortUtils.greater(array[i], array[i + 1])) { + SortUtils.swap(array, i, i + 1); + sorted = false; + } + } + return sorted; + } - private > boolean performEvenSort(T[] array) { - boolean sorted = true; - for (int i = 0; i < array.length - 1; i += 2) { - if (array[i].compareTo(array[i + 1]) > 0) { - SortUtils.swap(array, i, i + 1); - sorted = false; - } - } - return sorted; - } + private > boolean performEvenSort(T[] array) { + boolean sorted = true; + for (int i = 0; i < array.length - 1; i += 2) { + if (SortUtils.greater(array[i], array[i + 1])) { + SortUtils.swap(array, i, i + 1); + sorted = false; + } + } + return sorted; + } } diff --git a/src/main/java/com/thealgorithms/sorts/SelectionSort.java b/src/main/java/com/thealgorithms/sorts/SelectionSort.java index dbb2b88ffcef..0722e8350e77 100644 --- a/src/main/java/com/thealgorithms/sorts/SelectionSort.java +++ b/src/main/java/com/thealgorithms/sorts/SelectionSort.java @@ -1,30 +1,31 @@ package com.thealgorithms.sorts; public class SelectionSort implements SortAlgorithm { - /** - * Sorts an array of comparable elements in increasing order using the selection sort algorithm. - * - * @param array the array to be sorted - * @param the class of array elements - * @return the sorted array - */ - @Override - public > T[] sort(T[] array) { + /** + * Sorts an array of comparable elements in increasing order using the selection + * sort algorithm. + * + * @param array the array to be sorted + * @param the class of array elements + * @return the sorted array + */ + @Override + public > T[] sort(T[] array) { - for (int i = 0; i < array.length - 1; i++) { - final int minIndex = findIndexOfMin(array, i); - SortUtils.swap(array, i, minIndex); - } - return array; - } + for (int i = 0; i < array.length - 1; i++) { + final int minIndex = findIndexOfMin(array, i); + SortUtils.swap(array, i, minIndex); + } + return array; + } - private static > int findIndexOfMin(T[] array, final int startIndex) { - int minIndex = startIndex; - for (int i = startIndex + 1; i < array.length; i++) { - if (array[i].compareTo(array[minIndex]) < 0) { - minIndex = i; - } - } - return minIndex; - } + private static > int findIndexOfMin(T[] array, final int startIndex) { + int minIndex = startIndex; + for (int i = startIndex + 1; i < array.length; i++) { + if (SortUtils.less(array[i], array[minIndex])) { + minIndex = i; + } + } + return minIndex; + } } diff --git a/src/main/java/com/thealgorithms/sorts/SelectionSortRecursive.java b/src/main/java/com/thealgorithms/sorts/SelectionSortRecursive.java index 9d24542de592..d5cfdd37eca3 100644 --- a/src/main/java/com/thealgorithms/sorts/SelectionSortRecursive.java +++ b/src/main/java/com/thealgorithms/sorts/SelectionSortRecursive.java @@ -5,57 +5,59 @@ */ public class SelectionSortRecursive implements SortAlgorithm { - /** - * Sorts an array using recursive selection sort. - * - * @param array the array to be sorted - * @param the type of elements in the array (must be Comparable) - * @return the sorted array - */ - public > T[] sort(T[] array) { - if (array.length == 0) { - return array; - } - recursiveSelectionSort(array, 0); - return array; - } - - /** - * Recursively sorts the array using selection sort. - * - * @param array the array to be sorted - * @param index the current index to start sorting from - * @param the type of elements in the array (must be Comparable) - */ - private static > void recursiveSelectionSort(T[] array, final int index) { - if (index == array.length - 1) { - return; - } - - SortUtils.swap(array, index, findMinIndex(array, index)); - - // Recursively call selection sort for the remaining array - recursiveSelectionSort(array, index + 1); - } - - /** - * Finds the index of the minimum element in the array starting from the given index. - * - * @param array the array to search - * @param start the starting index for the search - * @param the type of elements in the array - * @return the index of the minimum element - */ - private static > int findMinIndex(T[] array, final int start) { - // Base case: if start is the last index, return start - if (start == array.length - 1) { - return start; - } - - // Recursive call to find the minimum index in the rest of the array - final int minIndexInRest = findMinIndex(array, start + 1); - - // Return the index of the smaller element between array[start] and the minimum element in the rest of the array - return array[start].compareTo(array[minIndexInRest]) < 0 ? start : minIndexInRest; - } + /** + * Sorts an array using recursive selection sort. + * + * @param array the array to be sorted + * @param the type of elements in the array (must be Comparable) + * @return the sorted array + */ + public > T[] sort(T[] array) { + if (array.length == 0) { + return array; + } + recursiveSelectionSort(array, 0); + return array; + } + + /** + * Recursively sorts the array using selection sort. + * + * @param array the array to be sorted + * @param index the current index to start sorting from + * @param the type of elements in the array (must be Comparable) + */ + private static > void recursiveSelectionSort(T[] array, final int index) { + if (index == array.length - 1) { + return; + } + + SortUtils.swap(array, index, findMinIndex(array, index)); + + // Recursively call selection sort for the remaining array + recursiveSelectionSort(array, index + 1); + } + + /** + * Finds the index of the minimum element in the array starting from the given + * index. + * + * @param array the array to search + * @param start the starting index for the search + * @param the type of elements in the array + * @return the index of the minimum element + */ + private static > int findMinIndex(T[] array, final int start) { + // Base case: if start is the last index, return start + if (start == array.length - 1) { + return start; + } + + // Recursive call to find the minimum index in the rest of the array + final int minIndexInRest = findMinIndex(array, start + 1); + + // Return the index of the smaller element between array[start] and the minimum + // element in the rest of the array + return SortUtils.less(array[start], array[minIndexInRest]) ? start : minIndexInRest; + } } diff --git a/src/main/java/com/thealgorithms/sorts/StalinSort.java b/src/main/java/com/thealgorithms/sorts/StalinSort.java index 5aaf530fd94c..bd086dc996e8 100644 --- a/src/main/java/com/thealgorithms/sorts/StalinSort.java +++ b/src/main/java/com/thealgorithms/sorts/StalinSort.java @@ -1,21 +1,21 @@ package com.thealgorithms.sorts; public class StalinSort implements SortAlgorithm { - @SuppressWarnings("unchecked") - public > T[] sort(T[] array) { - if (array.length == 0) { - return array; - } - int currentIndex = 0; - for (int i = 1; i < array.length; i++) { - if (array[i].compareTo(array[currentIndex]) >= 0) { - currentIndex++; - array[currentIndex] = array[i]; - } - } - // Create a result array with sorted elements - T[] result = (T[]) java.lang.reflect.Array.newInstance(array.getClass().getComponentType(), currentIndex + 1); - System.arraycopy(array, 0, result, 0, currentIndex + 1); - return result; - } + @SuppressWarnings("unchecked") + public > T[] sort(T[] array) { + if (array.length == 0) { + return array; + } + int currentIndex = 0; + for (int i = 1; i < array.length; i++) { + if (SortUtils.greaterOrEqual(array[i], array[currentIndex])) { + currentIndex++; + array[currentIndex] = array[i]; + } + } + // Create a result array with sorted elements + T[] result = (T[]) java.lang.reflect.Array.newInstance(array.getClass().getComponentType(), currentIndex + 1); + System.arraycopy(array, 0, result, 0, currentIndex + 1); + return result; + } }