> T[] sort(T[] unsorted) {
- return sort(Arrays.asList(unsorted)).toArray(unsorted);
- }
-
- /**
- * This method implements the Generic Counting Sort
- *
- * @param list The list to be sorted
- *
- * Sorts the list in increasing order The method uses list elements as keys
- * in the frequency map
- */
- @Override
- public > List sort(List list) {
- Map frequency = new TreeMap<>();
- // The final output array
- List sortedArray = new ArrayList<>(list.size());
-
- // Counting the frequency of @param array elements
- list.forEach(v -> frequency.put(v, frequency.getOrDefault(v, 0) + 1));
-
- // Filling the sortedArray
- for (Map.Entry element : frequency.entrySet()) {
- for (int j = 0; j < element.getValue(); j++) {
- sortedArray.add(element.getKey());
- }
- }
-
- return sortedArray;
- }
-
- /**
- * Stream Counting Sort The same as method {@link CountingSort#sort(List)} }
- * but this method uses stream API
- *
- * @param list The list to be sorted
- */
- private static > List streamSort(List list) {
- return list.stream().collect(toMap(k -> k, v -> 1, (v1, v2) -> v1 + v2, TreeMap::new)).entrySet().stream().flatMap(entry -> IntStream.rangeClosed(1, entry.getValue()).mapToObj(t -> entry.getKey())).collect(toList());
- }
-
- // Driver Program
- public static void main(String[] args) {
- // Integer Input
- List unsortedInts = Stream.of(4, 23, 6, 78, 1, 54, 23, 1, 9, 231, 9, 12).collect(toList());
- CountingSort countingSort = new CountingSort();
-
- System.out.println("Before Sorting:");
- print(unsortedInts);
-
- // Output => 1 1 4 6 9 9 12 23 23 54 78 231
- System.out.println("After Sorting:");
- print(countingSort.sort(unsortedInts));
- System.out.println("After Sorting By Streams:");
- print(streamSort(unsortedInts));
-
- System.out.println("\n------------------------------\n");
-
- // String Input
- List unsortedStrings = Stream.of("c", "a", "e", "b", "d", "a", "f", "g", "c").collect(toList());
-
- System.out.println("Before Sorting:");
- print(unsortedStrings);
-
- // Output => a a b c c d e f g
- System.out.println("After Sorting:");
- print(countingSort.sort(unsortedStrings));
-
- System.out.println("After Sorting By Streams:");
- print(streamSort(unsortedStrings));
- }
-}
From 2d6c39ce100855c87b41f0c3594586ba7fdd6fce Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Fri, 12 Jul 2024 20:03:54 +0200
Subject: [PATCH 009/558] feat: `CountingSort` implementation (#5287)
* feat: CountingSort
* checkstyle: fix formatting
* refactor: adding additional final modifiers
* refactor: restructure sorting, update docs and tests
* docs: typo fix
---------
Co-authored-by: Alex Klymenko
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
DIRECTORY.md | 2 +
.../com/thealgorithms/sorts/CountingSort.java | 60 +++++++++++++++++++
.../thealgorithms/sorts/CountingSortTest.java | 27 +++++++++
3 files changed, 89 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/sorts/CountingSort.java
create mode 100644 src/test/java/com/thealgorithms/sorts/CountingSortTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 2b1f43965304..aa1005027066 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -494,6 +494,7 @@
* [BucketSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BucketSort.java)
* [CircleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CircleSort.java)
* [CocktailShakerSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java)
+ * [CountingSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CountingSort.java)
* [CombSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CombSort.java)
* [CycleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CycleSort.java)
* [DNFSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DNFSort.java)
@@ -862,6 +863,7 @@
* [BucketSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BucketSortTest.java)
* [CircleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CircleSortTest.java)
* [CocktailShakerSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java)
+ * [CountingSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CountingSortTest.java)
* [CombSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CombSortTest.java)
* [DualPivotQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java)
* [DutchNationalFlagSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java)
diff --git a/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/CountingSort.java
new file mode 100644
index 000000000000..5d54205032d4
--- /dev/null
+++ b/src/main/java/com/thealgorithms/sorts/CountingSort.java
@@ -0,0 +1,60 @@
+package com.thealgorithms.sorts;
+
+import java.util.Arrays;
+
+/**
+ * A standard implementation of the Counting Sort algorithm for integer arrays.
+ * This implementation has a time complexity of O(n + k), where n is the number
+ * of elements in the input array and k is the range of the input.
+ * It works only with integer arrays.
+ *
+ * The space complexity is O(k), where k is the range of the input integers.
+ *
+ * Note: This implementation handles negative integers as it
+ * calculates the range based on the minimum and maximum values of the array.
+ *
+ */
+public final class CountingSort {
+ private CountingSort() {
+ }
+
+ /**
+ * Sorts an array of integers using the Counting Sort algorithm.
+ *
+ * @param array the array to be sorted
+ * @return the sorted array
+ */
+ public static int[] sort(int[] array) {
+ if (array.length == 0) {
+ return array;
+ }
+ final var stats = Arrays.stream(array).summaryStatistics();
+ final int min = stats.getMin();
+ int[] count = computeHistogram(array, min, stats.getMax() - min + 1);
+ toCumulative(count);
+ return reconstructSorted(count, min, array);
+ }
+
+ private static int[] computeHistogram(final int[] array, final int shift, final int spread) {
+ int[] res = new int[spread];
+ for (final var value : array) {
+ res[value - shift]++;
+ }
+ return res;
+ }
+
+ private static void toCumulative(int[] count) {
+ for (int i = 1; i < count.length; i++) {
+ count[i] += count[i - 1];
+ }
+ }
+
+ private static int[] reconstructSorted(final int[] cumulativeCount, final int shift, final int[] array) {
+ int[] res = new int[array.length];
+ for (int i = array.length - 1; i >= 0; i--) {
+ res[cumulativeCount[array[i] - shift] - 1] = array[i];
+ cumulativeCount[array[i] - shift]--;
+ }
+ return res;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/sorts/CountingSortTest.java b/src/test/java/com/thealgorithms/sorts/CountingSortTest.java
new file mode 100644
index 000000000000..2426de6f2807
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/CountingSortTest.java
@@ -0,0 +1,27 @@
+package com.thealgorithms.sorts;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+import java.util.stream.Stream;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class CountingSortTest {
+
+ record TestCase(int[] inputArray, int[] expectedArray) {
+ }
+
+ static Stream provideTestCases() {
+ return Stream.of(new TestCase(new int[] {}, new int[] {}), new TestCase(new int[] {4}, new int[] {4}), new TestCase(new int[] {6, 1, 99, 27, 15, 23, 36}, new int[] {1, 6, 15, 23, 27, 36, 99}), new TestCase(new int[] {6, 1, 27, 15, 23, 27, 36, 23}, new int[] {1, 6, 15, 23, 23, 27, 27, 36}),
+ new TestCase(new int[] {5, 5, 5, 5, 5}, new int[] {5, 5, 5, 5, 5}), new TestCase(new int[] {1, 2, 3, 4, 5}, new int[] {1, 2, 3, 4, 5}), new TestCase(new int[] {5, 4, 3, 2, 1}, new int[] {1, 2, 3, 4, 5}), new TestCase(new int[] {3, -1, 4, 1, 5, -9}, new int[] {-9, -1, 1, 3, 4, 5}),
+ new TestCase(new int[] {0, 0, 0, 0}, new int[] {0, 0, 0, 0}), new TestCase(new int[] {3, 3, -1, -1, 2, 2, 0, 0}, new int[] {-1, -1, 0, 0, 2, 2, 3, 3}), new TestCase(new int[] {-3, -2, -1, -5, -4}, new int[] {-5, -4, -3, -2, -1}),
+ new TestCase(new int[] {1000, 500, 100, 50, 10, 5, 1}, new int[] {1, 5, 10, 50, 100, 500, 1000}), new TestCase(new int[] {4, -5, 10, 0}, new int[] {-5, 0, 4, 10}));
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideTestCases")
+ public void testCountingSortException(TestCase testCase) {
+ int[] outputArray = CountingSort.sort(testCase.inputArray);
+ assertArrayEquals(testCase.expectedArray, outputArray);
+ }
+}
From 57878cac555eebf33a86b3d808e7b91f26174458 Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Sat, 13 Jul 2024 19:14:49 +0200
Subject: [PATCH 010/558] refactor: cleanup `CycleSort` (#5271)
* refactor: cleanup CycleSort. Adding test for it. Simplify code
* refactor: CycleSortTest to directory file
* tests: Adding more various tests cases for testing sorting algorithms
* checkstyle: imports and whitespaces fixes
* tests: removing boolean sorting
* checkstyle: fix "eedBraces: 'if' construct must use '{}'s"
* checkstyle: reduce "Too many static imports"
---------
Co-authored-by: Alex Klymenko
---
DIRECTORY.md | 1 +
.../com/thealgorithms/sorts/CycleSort.java | 121 +++++------
.../thealgorithms/sorts/CycleSortTest.java | 8 +
.../sorts/SortingAlgorithmTest.java | 191 ++++++++++++++++++
4 files changed, 252 insertions(+), 69 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/sorts/CycleSortTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index aa1005027066..02ad74351bd7 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -865,6 +865,7 @@
* [CocktailShakerSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java)
* [CountingSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CountingSortTest.java)
* [CombSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CombSortTest.java)
+ * [CycleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CycleSortTest.java)
* [DualPivotQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java)
* [DutchNationalFlagSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java)
* [ExchangeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java)
diff --git a/src/main/java/com/thealgorithms/sorts/CycleSort.java b/src/main/java/com/thealgorithms/sorts/CycleSort.java
index 0852abfaae24..e254dd8102d2 100644
--- a/src/main/java/com/thealgorithms/sorts/CycleSort.java
+++ b/src/main/java/com/thealgorithms/sorts/CycleSort.java
@@ -1,100 +1,83 @@
package com.thealgorithms.sorts;
-import static com.thealgorithms.sorts.SortUtils.less;
-import static com.thealgorithms.sorts.SortUtils.print;
-
/**
+ * This class implements the cycle sort algorithm.
+ * Cycle sort is an in-place sorting algorithm, unstable, and efficient for scenarios with limited memory usage.
* @author Podshivalov Nikita (https://github.com/nikitap492)
*/
class CycleSort implements SortAlgorithm {
-
+ /**
+ * Sorts an array of comparable elements using the cycle sort algorithm.
+ *
+ * @param array the array to be sorted
+ * @param the type of elements in the array, must be comparable
+ * @return the sorted array
+ */
@Override
- public > T[] sort(T[] arr) {
- int n = arr.length;
-
- // traverse array elements
- for (int j = 0; j <= n - 2; j++) {
- // initialize item as starting point
- T item = arr[j];
-
- // Find position where we put the item.
- int pos = j;
- for (int i = j + 1; i < n; i++) {
- if (less(arr[i], item)) {
+ public > T[] sort(T[] array) {
+ for (int cycleStart = 0; cycleStart <= array.length - 2; cycleStart++) {
+ T item = array[cycleStart];
+
+ // Find the position where we put the element
+ int pos = cycleStart;
+ for (int i = cycleStart + 1; i < array.length; i++) {
+ if (SortUtils.less(array[i], item)) {
pos++;
}
}
- // If item is already in correct position
- if (pos == j) {
+ // If the item is already in the correct position
+ if (pos == cycleStart) {
continue;
}
- // ignore all duplicate elements
- while (item.compareTo(arr[pos]) == 0) {
- pos += 1;
+ // Ignore all duplicate elements
+ while (item.compareTo(array[pos]) == 0) {
+ pos++;
}
- // put the item to it's right position
- if (pos != j) {
- item = replace(arr, pos, item);
+ // Put the item to its correct position
+ if (pos != cycleStart) {
+ item = replace(array, pos, item);
}
- // Rotate rest of the cycle
- while (pos != j) {
- pos = j;
+ // Rotate the rest of the cycle
+ while (pos != cycleStart) {
+ pos = cycleStart;
- // Find position where we put the element
- for (int i = j + 1; i < n; i++) {
- if (less(arr[i], item)) {
- pos += 1;
+ // Find the position where we put the element
+ for (int i = cycleStart + 1; i < array.length; i++) {
+ if (SortUtils.less(array[i], item)) {
+ pos++;
}
}
- // ignore all duplicate elements
- while (item.compareTo(arr[pos]) == 0) {
- pos += 1;
+ // Ignore all duplicate elements
+ while (item.compareTo(array[pos]) == 0) {
+ pos++;
}
- // put the item to it's right position
- if (item != arr[pos]) {
- item = replace(arr, pos, item);
+ // Put the item to its correct position
+ if (item != array[pos]) {
+ item = replace(array, pos, item);
}
}
}
-
- return arr;
- }
-
- private > T replace(T[] arr, int pos, T item) {
- T temp = item;
- item = arr[pos];
- arr[pos] = temp;
- return item;
+ return array;
}
- public static void main(String[] args) {
- Integer[] arr = {
- 4,
- 23,
- 6,
- 78,
- 1,
- 26,
- 11,
- 23,
- 0,
- -6,
- 3,
- 54,
- 231,
- 9,
- 12,
- };
- CycleSort cycleSort = new CycleSort();
- cycleSort.sort(arr);
-
- System.out.println("After sort : ");
- print(arr);
+ /**
+ * Replaces an element in the array with the given item and returns the replaced item.
+ *
+ * @param array the array in which the replacement will occur
+ * @param pos the position at which the replacement will occur
+ * @param item the item to be placed in the array
+ * @param the type of elements in the array, must be comparable
+ * @return the replaced item
+ */
+ private > T replace(T[] array, int pos, T item) {
+ T replacedItem = array[pos];
+ array[pos] = item;
+ return replacedItem;
}
}
diff --git a/src/test/java/com/thealgorithms/sorts/CycleSortTest.java b/src/test/java/com/thealgorithms/sorts/CycleSortTest.java
new file mode 100644
index 000000000000..b8c3d1653713
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/CycleSortTest.java
@@ -0,0 +1,8 @@
+package com.thealgorithms.sorts;
+
+public class CycleSortTest extends SortingAlgorithmTest {
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return new CycleSort();
+ }
+}
diff --git a/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java b/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java
index e6aedc3f06ac..43de55018071 100644
--- a/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java
+++ b/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java
@@ -1,11 +1,14 @@
package com.thealgorithms.sorts;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
import org.junit.jupiter.api.Test;
public abstract class SortingAlgorithmTest {
@@ -171,4 +174,192 @@ void shouldAcceptWhenRandomListIsPassed() {
List sorted = getSortAlgorithm().sort(list);
assertTrue(SortUtils.isSorted(sorted));
}
+
+ @Test
+ public void shouldAcceptWhenArrayWithAllIdenticalValuesIsPassed() {
+ Integer[] array = {1, 1, 1, 1};
+ Integer[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new Integer[] {1, 1, 1, 1}, sortedArray);
+ }
+
+ @Test
+ public void shouldAcceptWhenListWithAllIdenticalValuesIsPassed() {
+ List list = Arrays.asList(1, 1, 1, 1);
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList(1, 1, 1, 1), sortedList);
+ }
+
+ @Test
+ public void shouldAcceptWhenArrayWithMixedPositiveAndNegativeValuesIsPassed() {
+ Integer[] array = {-1, 3, -2, 5, 0};
+ Integer[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new Integer[] {-2, -1, 0, 3, 5}, sortedArray);
+ }
+
+ @Test
+ public void shouldAcceptWhenListWithMixedPositiveAndNegativeValuesIsPassed() {
+ List list = Arrays.asList(-1, 3, -2, 5, 0);
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList(-2, -1, 0, 3, 5), sortedList);
+ }
+
+ @Test
+ public void shouldAcceptWhenArrayWithLargeNumbersIsPassed() {
+ Long[] array = {10000000000L, 9999999999L, 10000000001L};
+ Long[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new Long[] {9999999999L, 10000000000L, 10000000001L}, sortedArray);
+ }
+
+ @Test
+ public void shouldAcceptWhenListWithLargeNumbersIsPassed() {
+ List list = Arrays.asList(10000000000L, 9999999999L, 10000000001L);
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList(9999999999L, 10000000000L, 10000000001L), sortedList);
+ }
+
+ @Test
+ public void shouldAcceptWhenArrayWithMaxIntegerValuesIsPassed() {
+ Integer[] array = {Integer.MAX_VALUE, Integer.MIN_VALUE, 0};
+ Integer[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new Integer[] {Integer.MIN_VALUE, 0, Integer.MAX_VALUE}, sortedArray);
+ }
+
+ @Test
+ public void shouldAcceptWhenListWithMaxIntegerValuesIsPassed() {
+ List list = Arrays.asList(Integer.MAX_VALUE, Integer.MIN_VALUE, 0);
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE), sortedList);
+ }
+
+ @Test
+ public void shouldAcceptWhenArrayWithMinIntegerValuesIsPassed() {
+ Integer[] array = {Integer.MIN_VALUE, Integer.MAX_VALUE, 0};
+ Integer[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new Integer[] {Integer.MIN_VALUE, 0, Integer.MAX_VALUE}, sortedArray);
+ }
+
+ @Test
+ public void shouldAcceptWhenListWithMinIntegerValuesIsPassed() {
+ List list = Arrays.asList(Integer.MIN_VALUE, Integer.MAX_VALUE, 0);
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE), sortedList);
+ }
+
+ @Test
+ public void shouldAcceptWhenArrayWithSpecialCharactersIsPassed() {
+ String[] array = {"!", "@", "#", "$"};
+ String[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new String[] {"!", "#", "$", "@"}, sortedArray);
+ }
+
+ @Test
+ public void shouldAcceptWhenListWithSpecialCharactersIsPassed() {
+ List list = Arrays.asList("!", "@", "#", "$");
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList("!", "#", "$", "@"), sortedList);
+ }
+
+ @Test
+ public void shouldAcceptWhenArrayWithMixedCaseStringsIsPassed() {
+ String[] array = {"apple", "Banana", "cherry", "Date"};
+ String[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new String[] {"Banana", "Date", "apple", "cherry"}, sortedArray);
+ }
+
+ @Test
+ public void shouldAcceptWhenListWithMixedCaseStringsIsPassed() {
+ List list = Arrays.asList("apple", "Banana", "cherry", "Date");
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList("Banana", "Date", "apple", "cherry"), sortedList);
+ }
+
+ @Test
+ public void shouldHandleArrayWithNullValues() {
+ Integer[] array = {3, null, 2, null, 1};
+ org.junit.jupiter.api.Assertions.assertThrows(NullPointerException.class, () -> getSortAlgorithm().sort(array));
+ }
+
+ @Test
+ public void shouldHandleListWithNullValues() {
+ List list = Arrays.asList(3, null, 2, null, 1);
+ org.junit.jupiter.api.Assertions.assertThrows(NullPointerException.class, () -> getSortAlgorithm().sort(list));
+ }
+
+ static class CustomObject implements Comparable {
+ int value;
+
+ CustomObject(int value) {
+ this.value = value;
+ }
+
+ @Override
+ public int compareTo(CustomObject o) {
+ return Integer.compare(this.value, o.value);
+ }
+
+ @Override
+ public String toString() {
+ return "CustomObject{"
+ + "value=" + value + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ CustomObject that = (CustomObject) o;
+ return value == that.value;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(value);
+ }
+ }
+
+ @Test
+ public void shouldHandleArrayOfCustomObjects() {
+ CustomObject[] array = {new CustomObject(3), new CustomObject(1), new CustomObject(2)};
+ CustomObject[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new CustomObject[] {new CustomObject(1), new CustomObject(2), new CustomObject(3)}, sortedArray);
+ }
+
+ @Test
+ public void shouldHandleListOfCustomObjects() {
+ List list = Arrays.asList(new CustomObject(3), new CustomObject(1), new CustomObject(2));
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList(new CustomObject(1), new CustomObject(2), new CustomObject(3)), sortedList);
+ }
+
+ @Test
+ public void shouldHandleArrayOfFloatingPointNumbers() {
+ Double[] array = {3.3, 2.2, 1.1, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY};
+ Double[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new Double[] {Double.NEGATIVE_INFINITY, 1.1, 2.2, 3.3, Double.POSITIVE_INFINITY, Double.NaN}, sortedArray);
+ }
+
+ @Test
+ public void shouldHandleListOfFloatingPointNumbers() {
+ List list = Arrays.asList(3.3, 2.2, 1.1, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList(Double.NEGATIVE_INFINITY, 1.1, 2.2, 3.3, Double.POSITIVE_INFINITY, Double.NaN), sortedList);
+ }
+
+ @Test
+ public void shouldHandleArrayWithEmptyStrings() {
+ String[] array = {"apple", "", "banana", ""};
+ String[] sortedArray = getSortAlgorithm().sort(array);
+ assertArrayEquals(new String[] {"", "", "apple", "banana"}, sortedArray);
+ }
+
+ @Test
+ public void shouldHandleListWithEmptyStrings() {
+ List list = Arrays.asList("apple", "", "banana", "");
+ List sortedList = getSortAlgorithm().sort(list);
+ assertEquals(Arrays.asList("", "", "apple", "banana"), sortedList);
+ }
}
From 5840579885e5132b6f2f9997d78707f3dcb63a14 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Tue, 16 Jul 2024 10:39:11 +0200
Subject: [PATCH 011/558] style: include `BigIntegerInstantiation` (#5294)
---
pmd-exclude.properties | 3 +--
.../thealgorithms/maths/FibonacciJavaStreams.java | 2 +-
.../maths/FibonacciJavaStreamsTest.java | 6 +++---
.../java/com/thealgorithms/maths/MatrixUtilTest.java | 12 ++++++------
4 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/pmd-exclude.properties b/pmd-exclude.properties
index b7bc6f074d02..1e7a09549aca 100644
--- a/pmd-exclude.properties
+++ b/pmd-exclude.properties
@@ -39,7 +39,6 @@ com.thealgorithms.dynamicprogramming.WineProblem=UselessParentheses
com.thealgorithms.maths.BinomialCoefficient=UselessParentheses
com.thealgorithms.maths.Complex=UselessParentheses
com.thealgorithms.maths.DistanceFormulaTest=UnnecessaryFullyQualifiedName
-com.thealgorithms.maths.FibonacciJavaStreamsTest=BigIntegerInstantiation
com.thealgorithms.maths.Gaussian=UselessParentheses
com.thealgorithms.maths.GcdSolutionWrapper=UselessParentheses
com.thealgorithms.maths.HeronsFormula=UselessParentheses
@@ -47,7 +46,7 @@ com.thealgorithms.maths.KaprekarNumbers=UselessParentheses
com.thealgorithms.maths.KeithNumber=UselessParentheses
com.thealgorithms.maths.LeonardoNumber=UselessParentheses
com.thealgorithms.maths.LinearDiophantineEquationsSolver=UselessParentheses
-com.thealgorithms.maths.MatrixUtil=BigIntegerInstantiation,UselessParentheses
+com.thealgorithms.maths.MatrixUtil=UselessParentheses
com.thealgorithms.maths.RomanNumeralUtil=UselessParentheses
com.thealgorithms.maths.SecondMinMax=UselessParentheses
com.thealgorithms.maths.SecondMinMaxTest=UnnecessaryFullyQualifiedName
diff --git a/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java b/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java
index 72bae57c27b0..84390860ccc4 100644
--- a/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java
+++ b/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java
@@ -22,7 +22,7 @@ public static Optional calculate(final BigDecimal index) {
return Optional.of(BigDecimal.ZERO);
}
- if (index.compareTo(new BigDecimal(2)) < 0) {
+ if (index.compareTo(BigDecimal.TWO) < 0) {
return Optional.of(BigDecimal.ONE);
}
diff --git a/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java b/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java
index 2c81a6304d8f..5cfb304ae471 100644
--- a/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java
+++ b/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java
@@ -21,13 +21,13 @@ public void testWithNegativeIndexShouldThrowException() {
public void testCheckTheFirst4SequenceElements() {
checkElement(BigDecimal.ZERO, BigDecimal.ZERO);
checkElement(BigDecimal.ONE, BigDecimal.ONE);
- checkElement(new BigDecimal(2), BigDecimal.ONE);
- checkElement(new BigDecimal(3), new BigDecimal(2));
+ checkElement(BigDecimal.TWO, BigDecimal.ONE);
+ checkElement(new BigDecimal(3), BigDecimal.TWO);
}
@Test
public void testCheck10thSequenceElement() {
- checkElement(new BigDecimal(10), new BigDecimal(55));
+ checkElement(BigDecimal.TEN, new BigDecimal(55));
}
@Test
diff --git a/src/test/java/com/thealgorithms/maths/MatrixUtilTest.java b/src/test/java/com/thealgorithms/maths/MatrixUtilTest.java
index f61ebe6a26cc..b954e6ff7511 100644
--- a/src/test/java/com/thealgorithms/maths/MatrixUtilTest.java
+++ b/src/test/java/com/thealgorithms/maths/MatrixUtilTest.java
@@ -11,20 +11,20 @@ class MatrixUtilTest {
@Test
void add() {
final BigDecimal[][] matrix1 = {
- {new BigDecimal(3), new BigDecimal(2)},
+ {new BigDecimal(3), BigDecimal.TWO},
{BigDecimal.ZERO, BigDecimal.ONE},
};
final BigDecimal[][] matrix2 = {
{BigDecimal.ONE, new BigDecimal(3)},
- {new BigDecimal(2), BigDecimal.ZERO},
+ {BigDecimal.TWO, BigDecimal.ZERO},
};
final BigDecimal[][] actual = MatrixUtil.add(matrix1, matrix2).orElseThrow(() -> new AssertionError("Could not compute matrix!"));
final BigDecimal[][] expected = {
{new BigDecimal(4), new BigDecimal(5)},
- {new BigDecimal(2), BigDecimal.ONE},
+ {BigDecimal.TWO, BigDecimal.ONE},
};
assertTrue(Objects.deepEquals(actual, expected));
@@ -37,7 +37,7 @@ void subtract() {
};
final BigDecimal[][] matrix2 = {
- {new BigDecimal(2), BigDecimal.ZERO},
+ {BigDecimal.TWO, BigDecimal.ZERO},
{new BigDecimal(-2), new BigDecimal(-3)},
};
@@ -55,13 +55,13 @@ void subtract() {
void multiply() {
final BigDecimal[][] matrix1 = {
- {BigDecimal.ONE, new BigDecimal(2), new BigDecimal(3)},
+ {BigDecimal.ONE, BigDecimal.TWO, new BigDecimal(3)},
{new BigDecimal(4), new BigDecimal(5), new BigDecimal(6)},
{new BigDecimal(7), new BigDecimal(8), new BigDecimal(9)},
};
final BigDecimal[][] matrix2 = {
- {BigDecimal.ONE, new BigDecimal(2)},
+ {BigDecimal.ONE, BigDecimal.TWO},
{new BigDecimal(3), new BigDecimal(4)},
{new BigDecimal(5), new BigDecimal(6)},
};
From ff0eca3caaaa91423248908216f29c6e1b8cc367 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 16 Jul 2024 11:57:28 +0300
Subject: [PATCH 012/558] Chore(deps): bump
org.apache.maven.plugins:maven-pmd-plugin from 3.23.0 to 3.24.0 (#5292)
---
DIRECTORY.md | 17 +++++++++++------
pom.xml | 2 +-
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 02ad74351bd7..191158bf6da0 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -494,8 +494,8 @@
* [BucketSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BucketSort.java)
* [CircleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CircleSort.java)
* [CocktailShakerSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java)
- * [CountingSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CountingSort.java)
* [CombSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CombSort.java)
+ * [CountingSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CountingSort.java)
* [CycleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CycleSort.java)
* [DNFSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DNFSort.java)
* [DualPivotQuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java)
@@ -528,8 +528,8 @@
* [TimSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TimSort.java)
* [TopologicalSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TopologicalSort.java)
* [TreeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TreeSort.java)
- * [WiggleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WiggleSort.java)
* [WaveSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WaveSort.java)
+ * [WiggleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WiggleSort.java)
* stacks
* [BalancedBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java)
* [DecimalToAnyUsingStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java)
@@ -761,6 +761,7 @@
* [LongDivisionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LongDivisionTest.java)
* [LucasSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java)
* [MatrixRankTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MatrixRankTest.java)
+ * [MatrixUtilTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MatrixUtilTest.java)
* [MaxValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MaxValueTest.java)
* [MeansTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MeansTest.java)
* [MedianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MedianTest.java)
@@ -831,6 +832,7 @@
* [NextFitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/NextFitTest.java)
* [PasswordGenTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/PasswordGenTest.java)
* [SieveOfEratosthenesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/SieveOfEratosthenesTest.java)
+ * [StringMatchFiniteAutomataTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/StringMatchFiniteAutomataTest.java)
* [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java)
* [TwoPointersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TwoPointersTest.java)
* [WorstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java)
@@ -857,14 +859,15 @@
* sorts
* [BeadSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BeadSortTest.java)
* [BinaryInsertionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java)
+ * [BitonicSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BitonicSortTest.java)
* [BogoSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BogoSortTest.java)
- * [BubbleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java)
* [BubbleSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BubbleSortRecursiveTest.java)
+ * [BubbleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java)
* [BucketSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BucketSortTest.java)
* [CircleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CircleSortTest.java)
* [CocktailShakerSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java)
- * [CountingSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CountingSortTest.java)
* [CombSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CombSortTest.java)
+ * [CountingSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CountingSortTest.java)
* [CycleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CycleSortTest.java)
* [DualPivotQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java)
* [DutchNationalFlagSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java)
@@ -873,13 +876,14 @@
* [HeapSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/HeapSortTest.java)
* [InsertionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java)
* [IntrospectiveSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java)
+ * [MergeSortNoExtraSpaceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortNoExtraSpaceTest.java)
* [MergeSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortRecursiveTest.java)
* [MergeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortTest.java)
* [OddEvenSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java)
* [PancakeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java)
* [QuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/QuickSortTest.java)
- * [SelectionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java)
* [SelectionSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java)
+ * [SelectionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java)
* [ShellSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/ShellSortTest.java)
* [SimpleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SimpleSortTest.java)
* [SlowSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SlowSortTest.java)
@@ -887,11 +891,12 @@
* [SortUtilsRandomGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java)
* [SortUtilsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java)
* [StrandSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/StrandSortTest.java)
+ * [SwapSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SwapSortTest.java)
* [TimSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TimSortTest.java)
* [TopologicalSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java)
* [TreeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TreeSortTest.java)
- * [WiggleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java)
* [WaveSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WaveSortTest.java)
+ * [WiggleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java)
* stacks
* [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java)
* strings
diff --git a/pom.xml b/pom.xml
index 7e363fcf258a..e08faac6385b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -146,7 +146,7 @@
org.apache.maven.plugins
maven-pmd-plugin
- 3.23.0
+ 3.24.0
true
true
From f584cd9a98f9a38d8ae930456fd69c0927220508 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 16 Jul 2024 11:05:17 +0200
Subject: [PATCH 013/558] Chore(deps): bump gitpod/workspace-java-21 from
2024-07-02-14-18-47 to 2024-07-14-17-19-51 (#5293)
Chore(deps): bump gitpod/workspace-java-21
Bumps gitpod/workspace-java-21 from 2024-07-02-14-18-47 to 2024-07-14-17-19-51.
---
updated-dependencies:
- dependency-name: gitpod/workspace-java-21
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.gitpod.dockerfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile
index 99a25f592e0a..e6d0001e5571 100644
--- a/.gitpod.dockerfile
+++ b/.gitpod.dockerfile
@@ -1,4 +1,4 @@
-FROM gitpod/workspace-java-21:2024-07-02-14-18-47
+FROM gitpod/workspace-java-21:2024-07-14-17-19-51
ENV LLVM_SCRIPT="tmp_llvm.sh"
From f1e26064a52096448c84037c08435f19adef60a4 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 18 Jul 2024 08:27:37 +0200
Subject: [PATCH 014/558] Chore(deps): bump org.apache.commons:commons-lang3
from 3.14.0 to 3.15.0 (#5296)
Bumps org.apache.commons:commons-lang3 from 3.14.0 to 3.15.0.
---
updated-dependencies:
- dependency-name: org.apache.commons:commons-lang3
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index e08faac6385b..0c01353aa5dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,7 +50,7 @@
org.apache.commons
commons-lang3
- 3.14.0
+ 3.15.0
org.apache.commons
From 94032148ca52092248ef43e8d7c0fa9ff6737e49 Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Fri, 19 Jul 2024 18:24:55 +0200
Subject: [PATCH 015/558] refactor: cleanup `RadixSort` (#5280)
* refactor: refactoring RadixSort, adding test, update DIRECTORY.md
* checkstyle: fix formatting for test
* refactor: adding possibility to sort negative numbers. Improve tests. Improving code readability
* checkstyle: fix formatting
* refactor: resolve conflicts with master branch
* refactor: remove negative integers support
* checkstyle: fix formatting
* checkstyle: fix formatting, revert test
* refactor: adding return array to countDigits and buildOutput method, adding more specific description to javadocs
---------
Co-authored-by: Alex Klymenko
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
DIRECTORY.md | 1 +
.../com/thealgorithms/sorts/RadixSort.java | 108 ++++++++++++------
.../thealgorithms/sorts/RadixSortTest.java | 30 +++++
3 files changed, 103 insertions(+), 36 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/sorts/RadixSortTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 191158bf6da0..ef7d163a5704 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -882,6 +882,7 @@
* [OddEvenSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java)
* [PancakeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java)
* [QuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/QuickSortTest.java)
+ * [RadixSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/RadixSortTest.java)
* [SelectionSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java)
* [SelectionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java)
* [ShellSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/ShellSortTest.java)
diff --git a/src/main/java/com/thealgorithms/sorts/RadixSort.java b/src/main/java/com/thealgorithms/sorts/RadixSort.java
index a87097bf6e9d..f0201a5a84b8 100644
--- a/src/main/java/com/thealgorithms/sorts/RadixSort.java
+++ b/src/main/java/com/thealgorithms/sorts/RadixSort.java
@@ -1,62 +1,98 @@
package com.thealgorithms.sorts;
+import com.thealgorithms.maths.NumberOfDigits;
import java.util.Arrays;
-final class RadixSort {
+/**
+ * This class provides an implementation of the radix sort algorithm.
+ * It sorts an array of nonnegative integers in increasing order.
+ */
+public final class RadixSort {
+ private static final int BASE = 10;
+
private RadixSort() {
}
- private static int getMax(int[] arr, int n) {
- int mx = arr[0];
- for (int i = 1; i < n; i++) {
- if (arr[i] > mx) {
- mx = arr[i];
- }
+ /**
+ * Sorts an array of nonnegative integers using the radix sort algorithm.
+ *
+ * @param array the array to be sorted
+ * @return the sorted array
+ * @throws IllegalArgumentException if any negative integers are found
+ */
+ public static int[] sort(int[] array) {
+ if (array.length == 0) {
+ return array;
}
- return mx;
- }
- private static void countSort(int[] arr, int n, int exp) {
- int[] output = new int[n];
- int i;
- int[] count = new int[10];
- Arrays.fill(count, 0);
+ checkForNegativeInput(array);
+ radixSort(array);
+ return array;
+ }
- for (i = 0; i < n; i++) {
- count[(arr[i] / exp) % 10]++;
+ /**
+ * Checks if the array contains any negative integers.
+ *
+ * @param array the array to be checked
+ * @throws IllegalArgumentException if any negative integers are found
+ */
+ private static void checkForNegativeInput(int[] array) {
+ for (int number : array) {
+ if (number < 0) {
+ throw new IllegalArgumentException("Array contains non-positive integers.");
+ }
}
+ }
- for (i = 1; i < 10; i++) {
- count[i] += count[i - 1];
+ private static void radixSort(int[] array) {
+ final int max = Arrays.stream(array).max().getAsInt();
+ for (int i = 0, exp = 1; i < NumberOfDigits.numberOfDigits(max); i++, exp *= BASE) {
+ countingSortByDigit(array, exp);
}
+ }
- for (i = n - 1; i >= 0; i--) {
- output[count[(arr[i] / exp) % 10] - 1] = arr[i];
- count[(arr[i] / exp) % 10]--;
- }
+ /**
+ * A utility method to perform counting sort of array[] according to the digit represented by exp.
+ *
+ * @param array the array to be sorted
+ * @param exp the exponent representing the current digit position
+ */
+ private static void countingSortByDigit(int[] array, int exp) {
+ int[] count = countDigits(array, exp);
+ accumulateCounts(count);
+ int[] output = buildOutput(array, exp, count);
+ copyOutput(array, output);
+ }
- System.arraycopy(output, 0, arr, 0, n);
+ private static int[] countDigits(int[] array, int exp) {
+ int[] count = new int[BASE];
+ for (int i = 0; i < array.length; i++) {
+ count[getDigit(array[i], exp)]++;
+ }
+ return count;
}
- private static void radixsort(int[] arr, int n) {
- int m = getMax(arr, n);
+ private static int getDigit(int number, int position) {
+ return (number / position) % BASE;
+ }
- for (int exp = 1; m / exp > 0; exp *= 10) {
- countSort(arr, n, exp);
+ private static void accumulateCounts(int[] count) {
+ for (int i = 1; i < BASE; i++) {
+ count[i] += count[i - 1];
}
}
- static void print(int[] arr, int n) {
- for (int i = 0; i < n; i++) {
- System.out.print(arr[i] + " ");
+ private static int[] buildOutput(int[] array, int exp, int[] count) {
+ int[] output = new int[array.length];
+ for (int i = array.length - 1; i >= 0; i--) {
+ int digit = getDigit(array[i], exp);
+ output[count[digit] - 1] = array[i];
+ count[digit]--;
}
+ return output;
}
- public static void main(String[] args) {
- int[] arr = {170, 45, 75, 90, 802, 24, 2, 66};
- int n = arr.length;
- radixsort(arr, n);
- print(arr, n);
+ private static void copyOutput(int[] array, int[] output) {
+ System.arraycopy(output, 0, array, 0, array.length);
}
}
-// Written by James Mc Dermott(theycallmemac)
diff --git a/src/test/java/com/thealgorithms/sorts/RadixSortTest.java b/src/test/java/com/thealgorithms/sorts/RadixSortTest.java
new file mode 100644
index 000000000000..24ab52b199aa
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/RadixSortTest.java
@@ -0,0 +1,30 @@
+package com.thealgorithms.sorts;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class RadixSortTest {
+ @ParameterizedTest
+ @MethodSource("provideTestCases")
+ public void test(int[] inputArray, int[] expectedArray) {
+ assertArrayEquals(RadixSort.sort(inputArray), expectedArray);
+ }
+
+ private static Stream provideTestCases() {
+ return Stream.of(Arguments.of(new int[] {170, 45, 75, 90, 802, 24, 2, 66}, new int[] {2, 24, 45, 66, 75, 90, 170, 802}), Arguments.of(new int[] {3, 3, 3, 3}, new int[] {3, 3, 3, 3}), Arguments.of(new int[] {9, 4, 6, 8, 14, 3}, new int[] {3, 4, 6, 8, 9, 14}),
+ Arguments.of(new int[] {10, 90, 49, 2, 1, 5, 23}, new int[] {1, 2, 5, 10, 23, 49, 90}), Arguments.of(new int[] {1, 3, 4, 2, 7, 8}, new int[] {1, 2, 3, 4, 7, 8}), Arguments.of(new int[] {}, new int[] {}), Arguments.of(new int[] {1}, new int[] {1}),
+ Arguments.of(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9}, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9}), Arguments.of(new int[] {9, 8, 7, 6, 5, 4, 3, 2, 1}, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9}),
+ Arguments.of(new int[] {1000000000, 999999999, 888888888, 777777777}, new int[] {777777777, 888888888, 999999999, 1000000000}), Arguments.of(new int[] {123, 9, 54321, 123456789, 0}, new int[] {0, 9, 123, 54321, 123456789}));
+ }
+
+ @Test
+ public void testWithNegativeNumbers() {
+ assertThrows(IllegalArgumentException.class, () -> RadixSort.sort(new int[] {3, 1, 4, 1, 5, -9}));
+ }
+}
From 97d416e64e0093bd28f64c36c9d29b59137d569e Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Sat, 20 Jul 2024 21:28:06 +0200
Subject: [PATCH 016/558] refactor: cleanup `StoogeSort` (#5283)
* refactor: cleanup StoogeSort
* refactor: update DIRECTORY.md for StoogeSortTest
---------
Co-authored-by: Alex Klymenko
---
DIRECTORY.md | 1 +
.../com/thealgorithms/sorts/StoogeSort.java | 29 ++++---------------
.../thealgorithms/sorts/StoogeSortTest.java | 12 ++++++++
3 files changed, 19 insertions(+), 23 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/sorts/StoogeSortTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index ef7d163a5704..0c14970bf481 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -891,6 +891,7 @@
* [SortingAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java)
* [SortUtilsRandomGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java)
* [SortUtilsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java)
+ * [StoogeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/StoogeSortTest.java)
* [StrandSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/StrandSortTest.java)
* [SwapSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SwapSortTest.java)
* [TimSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TimSortTest.java)
diff --git a/src/main/java/com/thealgorithms/sorts/StoogeSort.java b/src/main/java/com/thealgorithms/sorts/StoogeSort.java
index 330f9752d1e4..25830109638a 100644
--- a/src/main/java/com/thealgorithms/sorts/StoogeSort.java
+++ b/src/main/java/com/thealgorithms/sorts/StoogeSort.java
@@ -7,9 +7,12 @@
public class StoogeSort implements SortAlgorithm {
@Override
- public > T[] sort(T[] unsortedArray) {
- sort(unsortedArray, 0, unsortedArray.length);
- return unsortedArray;
+ public > T[] sort(T[] array) {
+ if (array.length == 0) {
+ return array;
+ }
+ sort(array, 0, array.length);
+ return array;
}
public > T[] sort(T[] unsortedArray, int start, int end) {
@@ -28,24 +31,4 @@ public > T[] sort(T[] unsortedArray, int start, int end)
}
return unsortedArray;
}
-
- public static void main(String[] args) {
- StoogeSort stoogeSort = new StoogeSort();
-
- Integer[] integerArray = {8, 84, 53, 953, 64, 2, 202};
- // Print integerArray unsorted
- SortUtils.print(integerArray);
-
- stoogeSort.sort(integerArray);
- // Print integerArray sorted
- SortUtils.print(integerArray);
-
- String[] stringArray = {"g", "d", "a", "b", "f", "c", "e"};
- // Print stringArray unsorted
- SortUtils.print(stringArray);
-
- stoogeSort.sort(stringArray);
- // Print stringArray sorted
- SortUtils.print(stringArray);
- }
}
diff --git a/src/test/java/com/thealgorithms/sorts/StoogeSortTest.java b/src/test/java/com/thealgorithms/sorts/StoogeSortTest.java
new file mode 100644
index 000000000000..e230ac2ac590
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/StoogeSortTest.java
@@ -0,0 +1,12 @@
+package com.thealgorithms.sorts;
+
+public class StoogeSortTest extends SortingAlgorithmTest {
+ protected int getGeneratedArraySize() {
+ return 1000;
+ }
+
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return new StoogeSort();
+ }
+}
From 08db744240782df6a4e985be157275d88cc99ef6 Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Mon, 22 Jul 2024 09:20:59 +0200
Subject: [PATCH 017/558] refactor: cleanup `PancakeSort` (#5295)
* refactor: PancakeSort cleanup, changing test to standard
* checkstyle: fix formatting
---------
Co-authored-by: alxklm
---
.../com/thealgorithms/sorts/PancakeSort.java | 71 ++++++----------
.../thealgorithms/sorts/PancakeSortTest.java | 80 +------------------
2 files changed, 29 insertions(+), 122 deletions(-)
diff --git a/src/main/java/com/thealgorithms/sorts/PancakeSort.java b/src/main/java/com/thealgorithms/sorts/PancakeSort.java
index cd3e89307238..6079672a1d77 100644
--- a/src/main/java/com/thealgorithms/sorts/PancakeSort.java
+++ b/src/main/java/com/thealgorithms/sorts/PancakeSort.java
@@ -10,56 +10,35 @@ public class PancakeSort implements SortAlgorithm {
@Override
public > T[] sort(T[] array) {
- int size = array.length;
+ if (array.length < 2) {
+ return array;
+ }
- for (int i = 0; i < size; i++) {
- T max = array[0];
- int index = 0;
- for (int j = 0; j < size - i; j++) {
- if (SortUtils.less(max, array[j])) {
- max = array[j];
- index = j;
- }
- }
- SortUtils.flip(array, index, array.length - 1 - i);
+ for (int currentSize = 0; currentSize < array.length; currentSize++) {
+ int maxIndex = findMaxIndex(array, currentSize);
+ SortUtils.flip(array, maxIndex, array.length - 1 - currentSize);
}
+
return array;
}
- public static void main(String[] args) {
- Integer[] arr = {
- 10,
- 9,
- 8,
- 7,
- 6,
- 15,
- 14,
- 7,
- 4,
- 3,
- 8,
- 6,
- 3,
- 1,
- 2,
- -2,
- -5,
- -8,
- -3,
- -1,
- 13,
- 12,
- 11,
- 5,
- 4,
- 3,
- 2,
- 1,
- };
- PancakeSort pancakeSort = new PancakeSort();
- System.out.println("After sorting:");
- pancakeSort.sort(arr);
- SortUtils.print(arr);
+ /**
+ * Finds the index of the maximum element in the array up to the given size.
+ *
+ * @param array the array to be searched
+ * @param currentSize the current size of the unsorted portion of the array
+ * @param the type of elements in the array
+ * @return the index of the maximum element
+ */
+ private > int findMaxIndex(T[] array, int currentSize) {
+ T max = array[0];
+ int maxIndex = 0;
+ for (int i = 0; i < array.length - currentSize; i++) {
+ if (SortUtils.less(max, array[i])) {
+ max = array[i];
+ maxIndex = i;
+ }
+ }
+ return maxIndex;
}
}
diff --git a/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java b/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java
index 8d26532a1acd..0039bdfb03e7 100644
--- a/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java
+++ b/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java
@@ -1,80 +1,8 @@
package com.thealgorithms.sorts;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-
-public class PancakeSortTest {
-
- private PancakeSort pancakeSort = new PancakeSort();
-
- @Test
- @DisplayName("Empty Array pancakeSort")
- public void pancakeSortEmptyArray() {
- Integer[] inputArray = {};
- Integer[] outputArray = pancakeSort.sort(inputArray);
- assertThat(outputArray).isEmpty();
- }
-
- @Test
- @DisplayName("PancakeSort single Integer Array")
- public void pancakeSort() {
- Integer[] inputArray = {2};
- Integer[] outputArray = pancakeSort.sort(inputArray);
- assertThat(outputArray).isEqualTo(inputArray);
- }
-
- @Test
- @DisplayName("PancakeSort non duplicate Integer Array")
- public void pancakeSortNonDuplicateIntegerArray() {
- Integer[] inputArray = {2, 1, 77, 34, 14, 56, 8};
- Integer[] expectedOutput = {1, 2, 8, 14, 34, 56, 77};
- Integer[] outputArray = pancakeSort.sort(inputArray);
- assertThat(outputArray).isEqualTo(expectedOutput);
- }
-
- @Test
- @DisplayName("PancakeSort Integer Array with duplicates")
- public void pancakeSortDuplicateIntegerArray() {
- Integer[] inputArray = {2, 1, 77, 34, 14, 77, 56, 14, 8};
- Integer[] expectedOutput = {1, 2, 8, 14, 14, 34, 56, 77, 77};
- Integer[] outputArray = pancakeSort.sort(inputArray);
- assertThat(outputArray).isEqualTo(expectedOutput);
- }
-
- @Test
- @DisplayName("PancakeSort negative Integer Array with duplicates")
- public void pancakeSortNegativeDuplicateIntegerArray() {
- Integer[] inputArray = {2, 1, 77, -34, -14, 77, 56, -14, 8};
- Integer[] expectedOutput = {-34, -14, -14, 1, 2, 8, 56, 77, 77};
- Integer[] outputArray = pancakeSort.sort(inputArray);
- assertThat(outputArray).isEqualTo(expectedOutput);
- }
-
- @Test
- @DisplayName("PancakeSort single String Array")
- public void pancakeSortSingleStringArray() {
- String[] inputArray = {"W"};
- String[] outputArray = pancakeSort.sort(inputArray);
- assertThat(outputArray).isEqualTo(inputArray);
- }
-
- @Test
- @DisplayName("PancakeSort non duplicate String Array")
- public void pancakeSortNonDuplicateStringArray() {
- String[] inputArray = {"W", "A", "d", "be", "jk", "hb", "bgh"};
- String[] expectedOutput = {"A", "W", "be", "bgh", "d", "hb", "jk"};
- String[] outputArray = pancakeSort.sort(inputArray);
- assertThat(outputArray).isEqualTo(expectedOutput);
- }
-
- @Test
- @DisplayName("PancakeSort String Array with duplicates")
- public void pancakeSortDuplicateStringArray() {
- String[] inputArray = {"W", "A", "d", "be", "jk", "hb", "bgh", "bgh", "W"};
- String[] expectedOutput = {"A", "W", "W", "be", "bgh", "bgh", "d", "hb", "jk"};
- String[] outputArray = pancakeSort.sort(inputArray);
- assertThat(outputArray).isEqualTo(expectedOutput);
+public class PancakeSortTest extends SortingAlgorithmTest {
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return new PancakeSort();
}
}
From 76a450fb75613c07c337af1604e31237f307c6c9 Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Wed, 24 Jul 2024 18:32:47 +0300
Subject: [PATCH 018/558] feat: add `PatienceSort` (#5288)
* feat: PatienceSort
* refactor: fix readability issues,a and redundant check
---------
Co-authored-by: alxklm
---
DIRECTORY.md | 2 +
.../com/thealgorithms/sorts/PatienceSort.java | 112 ++++++++++++++++++
.../thealgorithms/sorts/PatienceSortTest.java | 8 ++
3 files changed, 122 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/sorts/PatienceSort.java
create mode 100644 src/test/java/com/thealgorithms/sorts/PatienceSortTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 0c14970bf481..7e726f3191c6 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -511,6 +511,7 @@
* [MergeSortRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java)
* [OddEvenSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/OddEvenSort.java)
* [PancakeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PancakeSort.java)
+ * [PatienceSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PatienceSort.java)
* [PigeonholeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java)
* [QuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/QuickSort.java)
* [RadixSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/RadixSort.java)
@@ -881,6 +882,7 @@
* [MergeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortTest.java)
* [OddEvenSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java)
* [PancakeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java)
+ * [PatienceSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PatienceSortTest.java)
* [QuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/QuickSortTest.java)
* [RadixSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/RadixSortTest.java)
* [SelectionSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java)
diff --git a/src/main/java/com/thealgorithms/sorts/PatienceSort.java b/src/main/java/com/thealgorithms/sorts/PatienceSort.java
new file mode 100644
index 000000000000..52ed30d586b3
--- /dev/null
+++ b/src/main/java/com/thealgorithms/sorts/PatienceSort.java
@@ -0,0 +1,112 @@
+package com.thealgorithms.sorts;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.PriorityQueue;
+
+/**
+ * This class implements the Patience Sort algorithm. Patience Sort is a sorting algorithm that
+ * is particularly good for sorting sequences that are already partially sorted.
+ */
+public class PatienceSort implements SortAlgorithm {
+
+ /**
+ * Sorts an array of comparable elements using the Patience Sort algorithm.
+ *
+ * @param array the array to be sorted
+ * @param the type of elements in the array, must be comparable
+ * @return the sorted array
+ */
+ @Override
+ public > T[] sort(T[] array) {
+ if (array.length == 0) {
+ return array;
+ }
+
+ final List> piles = formPiles(array);
+ final PriorityQueue> pq = mergePiles(piles);
+ extractPiles(array, pq);
+
+ return array;
+ }
+
+ /**
+ * Forms piles from the given array. Each pile is a list of elements where
+ * each element is smaller than the one before it. Binary search is used
+ * to find the appropriate pile for each element.
+ *
+ * @param array the array of elements to be organized into piles
+ * @param the type of elements in the array, must be comparable
+ * @return a list of piles
+ */
+ private static > List> formPiles(final T[] array) {
+ final List> piles = new ArrayList<>();
+ final List lastElements = new ArrayList<>();
+
+ for (T x : array) {
+ int pos = Collections.binarySearch(lastElements, x);
+ if (pos < 0) {
+ pos = -pos - 1;
+ }
+
+ if (pos < piles.size()) {
+ piles.get(pos).add(x);
+ lastElements.set(pos, x);
+ } else {
+ List newPile = new ArrayList<>();
+ newPile.add(x);
+ piles.add(newPile);
+ lastElements.add(x);
+ }
+ }
+
+ return piles;
+ }
+
+ /**
+ * Merges the piles into a priority queue where the smallest elements are
+ * prioritized.
+ *
+ * @param piles the list of piles to be merged
+ * @param the type of elements in the piles, must be comparable
+ * @return a priority queue containing the top element of each pile
+ */
+ private static > PriorityQueue> mergePiles(final List> piles) {
+ PriorityQueue> pq = new PriorityQueue<>();
+ for (List pile : piles) {
+ pq.add(new PileNode<>(pile.removeLast(), pile));
+ }
+ return pq;
+ }
+
+ /**
+ * Extracts elements from the priority queue to form the sorted array.
+ *
+ * @param array the array to be filled with sorted elements
+ * @param pq the priority queue containing the elements to be extracted
+ * @param the type of elements in the array, must be comparable
+ */
+ private static > void extractPiles(final T[] array, final PriorityQueue> pq) {
+ int index = 0;
+ while (!pq.isEmpty()) {
+ PileNode node = pq.poll();
+ array[index++] = node.value;
+ if (!node.pile.isEmpty()) {
+ pq.add(new PileNode<>(node.pile.removeLast(), node.pile));
+ }
+ }
+ }
+
+ /**
+ * A helper record representing a node in the priority queue.
+ *
+ * @param the type of elements in the node, must be comparable
+ */
+ private record PileNode>(T value, List pile) implements Comparable> {
+ @Override
+ public int compareTo(PileNode other) {
+ return this.value.compareTo(other.value);
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/sorts/PatienceSortTest.java b/src/test/java/com/thealgorithms/sorts/PatienceSortTest.java
new file mode 100644
index 000000000000..f3cf7874f3b1
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/PatienceSortTest.java
@@ -0,0 +1,8 @@
+package com.thealgorithms.sorts;
+
+public class PatienceSortTest extends SortingAlgorithmTest {
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return new PatienceSort();
+ }
+}
From ebed8b38b834b89c1cbccd19fa6bd09b60ff86dc Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Thu, 25 Jul 2024 22:55:27 +0300
Subject: [PATCH 019/558] refactor: cleanup `PigeonholeSort` (#5298)
* refactor: PigeonholeSort
* checkstyle: fix formatting
* checkstyle: make class final
* refactor: changing negative numbers check first, fix typo, adding one more test for negative numbers
---------
Co-authored-by: Alex Klymenko
Co-authored-by: vil02 <65706193+vil02@users.noreply.github.com>
---
.../thealgorithms/sorts/PigeonholeSort.java | 106 ++++++++++++------
.../sorts/PigeonholeSortTest.java | 31 +++++
2 files changed, 101 insertions(+), 36 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/sorts/PigeonholeSortTest.java
diff --git a/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java b/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java
index 42fd026b117b..78d7d81d709f 100644
--- a/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java
+++ b/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java
@@ -1,55 +1,89 @@
package com.thealgorithms.sorts;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
-public class PigeonholeSort {
+public final class PigeonholeSort {
+ private PigeonholeSort() {
+ }
- /*
- This code implements the pigeonhole sort algorithm for the integer array,
- but we can also implement this for string arrays too.
- See https://www.geeksforgeeks.org/pigeonhole-sort/
- */
- void sort(Integer[] array) {
- int maxElement = array[0];
- for (int element : array) {
- if (element > maxElement) {
- maxElement = element;
- }
- }
+ /**
+ * Sorts the given array using the pigeonhole sort algorithm.
+ *
+ * @param array the array to be sorted
+ * @throws IllegalArgumentException if any negative integers are found
+ * @return the sorted array
+ */
+ public static int[] sort(int[] array) {
- int numOfPigeonholes = 1 + maxElement;
- ArrayList[] pigeonHole = new ArrayList[numOfPigeonholes];
+ checkForNegativeInput(array);
- for (int k = 0; k < numOfPigeonholes; k++) {
- pigeonHole[k] = new ArrayList<>();
+ if (array.length == 0) {
+ return array;
}
- for (int t : array) {
- pigeonHole[t].add(t);
- }
+ final int maxElement = Arrays.stream(array).max().orElseThrow();
+ final List> pigeonHoles = createPigeonHoles(maxElement);
+
+ populatePigeonHoles(array, pigeonHoles);
+ collectFromPigeonHoles(array, pigeonHoles);
+
+ return array;
+ }
- int k = 0;
- for (ArrayList ph : pigeonHole) {
- for (int elements : ph) {
- array[k] = elements;
- k = k + 1;
+ /**
+ * Checks if the array contains any negative integers.
+ *
+ * @param array the array to be checked
+ * @throws IllegalArgumentException if any negative integers are found
+ */
+ private static void checkForNegativeInput(int[] array) {
+ for (final int number : array) {
+ if (number < 0) {
+ throw new IllegalArgumentException("Array contains negative integers.");
}
}
}
- public static void main(String[] args) {
- PigeonholeSort pigeonholeSort = new PigeonholeSort();
- Integer[] arr = {8, 3, 2, 7, 4, 6, 8};
-
- System.out.print("Unsorted order is : ");
- SortUtils.print(arr);
+ /**
+ * Creates pigeonholes for sorting using an ArrayList of ArrayLists.
+ *
+ * @param maxElement the maximum element in the array
+ * @return an ArrayList of ArrayLists
+ */
+ private static List> createPigeonHoles(int maxElement) {
+ List> pigeonHoles = new ArrayList<>(maxElement + 1);
+ for (int i = 0; i <= maxElement; i++) {
+ pigeonHoles.add(new ArrayList<>());
+ }
+ return pigeonHoles;
+ }
- pigeonholeSort.sort(arr);
+ /**
+ * Populates the pigeonholes with elements from the array.
+ *
+ * @param array the array to be sorted
+ * @param pigeonHoles the pigeonholes to be populated
+ */
+ private static void populatePigeonHoles(int[] array, List> pigeonHoles) {
+ for (int element : array) {
+ pigeonHoles.get(element).add(element);
+ }
+ }
- System.out.print("Sorted order is : ");
- for (int i = 0; i < arr.length; i++) {
- assert (arr[i]) <= (arr[i + 1]);
+ /**
+ * Collects sorted elements from the pigeonholes back into the array.
+ *
+ * @param array the array to be sorted
+ * @param pigeonHoles the populated pigeonholes
+ */
+ private static void collectFromPigeonHoles(int[] array, List> pigeonHoles) {
+ int index = 0;
+ for (final var pigeonHole : pigeonHoles) {
+ for (final int element : pigeonHole) {
+ array[index++] = element;
+ }
}
- SortUtils.print(arr);
}
}
diff --git a/src/test/java/com/thealgorithms/sorts/PigeonholeSortTest.java b/src/test/java/com/thealgorithms/sorts/PigeonholeSortTest.java
new file mode 100644
index 000000000000..d1772de83701
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/PigeonholeSortTest.java
@@ -0,0 +1,31 @@
+package com.thealgorithms.sorts;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class PigeonholeSortTest {
+
+ @ParameterizedTest
+ @MethodSource("provideArraysForPigeonholeSort")
+ public void testPigeonholeSort(int[] inputArray, int[] expectedArray) {
+ PigeonholeSort.sort(inputArray);
+ assertArrayEquals(expectedArray, inputArray);
+ }
+
+ private static Stream provideArraysForPigeonholeSort() {
+ return Stream.of(Arguments.of(new int[] {}, new int[] {}), Arguments.of(new int[] {4}, new int[] {4}), Arguments.of(new int[] {6, 1, 99, 27, 15, 23, 36}, new int[] {1, 6, 15, 23, 27, 36, 99}), Arguments.of(new int[] {6, 1, 27, 15, 23, 27, 36, 23}, new int[] {1, 6, 15, 23, 23, 27, 27, 36}),
+ Arguments.of(new int[] {5, 5, 5, 5, 5}, new int[] {5, 5, 5, 5, 5}), Arguments.of(new int[] {1, 2, 3, 4, 5}, new int[] {1, 2, 3, 4, 5}), Arguments.of(new int[] {5, 4, 3, 2, 1}, new int[] {1, 2, 3, 4, 5}));
+ }
+
+ @Test
+ public void testWithNegativeNumbers() {
+ assertThrows(IllegalArgumentException.class, () -> PigeonholeSort.sort(new int[] {3, 1, 4, 1, 5, -9}));
+ assertThrows(IllegalArgumentException.class, () -> PigeonholeSort.sort(new int[] {-1}));
+ }
+}
From 5113101e5dd4eb2d74a8c9f5e15b73773b974bb5 Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Fri, 26 Jul 2024 09:55:11 +0300
Subject: [PATCH 020/558] refactor: cleanup `ShellSort` (#5302)
---
.../com/thealgorithms/sorts/ShellSort.java | 69 ++++++++++++-------
.../thealgorithms/sorts/ShellSortTest.java | 66 ++----------------
2 files changed, 50 insertions(+), 85 deletions(-)
diff --git a/src/main/java/com/thealgorithms/sorts/ShellSort.java b/src/main/java/com/thealgorithms/sorts/ShellSort.java
index 37a50e855698..d12b181e65a2 100644
--- a/src/main/java/com/thealgorithms/sorts/ShellSort.java
+++ b/src/main/java/com/thealgorithms/sorts/ShellSort.java
@@ -11,36 +11,59 @@ public class ShellSort implements SortAlgorithm {
*/
@Override
public > T[] sort(T[] array) {
- int length = array.length;
- int gap = 1;
-
- /* Calculate gap for optimization purpose */
- while (gap < length / 3) {
- gap = 3 * gap + 1;
+ if (array.length == 0) {
+ return array;
}
- for (; gap > 0; gap /= 3) {
- for (int i = gap; i < length; i++) {
- int j;
- T temp = array[i];
- for (j = i; j >= gap && SortUtils.less(temp, array[j - gap]); j -= gap) {
- array[j] = array[j - gap];
- }
- array[j] = temp;
- }
+ int gap = calculateInitialGap(array.length);
+
+ while (gap > 0) {
+ performGapInsertionSort(array, gap);
+ gap = calculateNextGap(gap);
}
+
return array;
}
- /* Driver Code */
- public static void main(String[] args) {
- Integer[] toSort = {4, 23, 6, 78, 1, 54, 231, 9, 12};
+ /**
+ * Calculates the initial gap value using the Knuth sequence.
+ *
+ * @param length the length of the array.
+ * @return the initial gap value.
+ */
+ private int calculateInitialGap(final int length) {
+ int gap = 1;
+ while (gap < length / 3) {
+ gap = 3 * gap + 1;
+ }
+ return gap;
+ }
+
+ /**
+ * Calculates the next gap value.
+ *
+ * @param currentGap the current gap value.
+ * @return the next gap value.
+ */
+ private int calculateNextGap(final int currentGap) {
+ return currentGap / 3;
+ }
- ShellSort sort = new ShellSort();
- sort.sort(toSort);
- for (int i = 0; i < toSort.length - 1; ++i) {
- assert toSort[i] <= toSort[i + 1];
+ /**
+ * Performs an insertion sort for the specified gap value.
+ *
+ * @param array the array to be sorted.
+ * @param gap the current gap value.
+ * @param the type of elements in the array.
+ */
+ private > void performGapInsertionSort(final T[] array, final int gap) {
+ for (int i = gap; i < array.length; i++) {
+ T temp = array[i];
+ int j;
+ for (j = i; j >= gap && SortUtils.less(temp, array[j - gap]); j -= gap) {
+ array[j] = array[j - gap];
+ }
+ array[j] = temp;
}
- SortUtils.print(toSort);
}
}
diff --git a/src/test/java/com/thealgorithms/sorts/ShellSortTest.java b/src/test/java/com/thealgorithms/sorts/ShellSortTest.java
index 73be91b397bd..b41f2c2e863b 100644
--- a/src/test/java/com/thealgorithms/sorts/ShellSortTest.java
+++ b/src/test/java/com/thealgorithms/sorts/ShellSortTest.java
@@ -1,66 +1,8 @@
package com.thealgorithms.sorts;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-
-import org.junit.jupiter.api.Test;
-
-public class ShellSortTest {
-
- private ShellSort shellSort = new ShellSort();
-
- @Test
- public void shellSortEmptyArray() {
- Integer[] inputArray = {};
- Integer[] outputArray = shellSort.sort(inputArray);
- Integer[] expectedOutput = {};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void shellSortSingleIntegerArray() {
- Integer[] inputArray = {4};
- Integer[] outputArray = shellSort.sort(inputArray);
- Integer[] expectedOutput = {4};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void shellSortSingleStringArray() {
- String[] inputArray = {"s"};
- String[] outputArray = shellSort.sort(inputArray);
- String[] expectedOutput = {"s"};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void shellSortNonDuplicateIntegerArray() {
- Integer[] inputArray = {6, -1, 99, 27, -15, 23, -36};
- Integer[] outputArray = shellSort.sort(inputArray);
- Integer[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void shellSortDuplicateIntegerArray() {
- Integer[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23};
- Integer[] outputArray = shellSort.sort(inputArray);
- Integer[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void shellSortNonDuplicateStringArray() {
- String[] inputArray = {"s", "b", "k", "a", "d", "c", "h"};
- String[] outputArray = shellSort.sort(inputArray);
- String[] expectedOutput = {"a", "b", "c", "d", "h", "k", "s"};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void shellSortDuplicateStringArray() {
- String[] inputArray = {"s", "b", "d", "a", "d", "c", "h", "b"};
- String[] outputArray = shellSort.sort(inputArray);
- String[] expectedOutput = {"a", "b", "b", "c", "d", "d", "h", "s"};
- assertArrayEquals(outputArray, expectedOutput);
+public class ShellSortTest extends SortingAlgorithmTest {
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return new ShellSort();
}
}
From fccd1410148a9bdda0d6cf2ddbf5ec10927c6260 Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Fri, 2 Aug 2024 09:06:45 +0200
Subject: [PATCH 021/558] refactor: cleanup `CombSort` (#5303)
refactor: cleanup CombSort
Co-authored-by: Alex Klymenko
---
.../com/thealgorithms/sorts/CombSort.java | 89 ++++++++-----------
.../com/thealgorithms/sorts/CombSortTest.java | 66 +-------------
2 files changed, 39 insertions(+), 116 deletions(-)
diff --git a/src/main/java/com/thealgorithms/sorts/CombSort.java b/src/main/java/com/thealgorithms/sorts/CombSort.java
index edf09a2eb3f8..cd12a5b2853c 100644
--- a/src/main/java/com/thealgorithms/sorts/CombSort.java
+++ b/src/main/java/com/thealgorithms/sorts/CombSort.java
@@ -16,76 +16,57 @@
* @see SortAlgorithm
*/
class CombSort implements SortAlgorithm {
+ private static final double SHRINK_FACTOR = 1.3;
- // To find gap between elements
- private int nextGap(int gap) {
- // Shrink gap by Shrink factor
- gap = (gap * 10) / 13;
+ /**
+ * Method to find the next gap
+ *
+ * @param gap the current gap
+ * @return the next gap value
+ */
+ private int getNextGap(int gap) {
+ gap = (int) (gap / SHRINK_FACTOR);
return Math.max(gap, 1);
}
/**
- * Function to sort arr[] using Comb
+ * Method to sort the array using CombSort
*
- * @param arr - an array should be sorted
- * @return sorted array
+ * @param arr the array to be sorted
+ * @param the type of elements in the array
+ * @return the sorted array
*/
@Override
public > T[] sort(T[] arr) {
- int size = arr.length;
-
- // initialize gap
- int gap = size;
-
- // Initialize swapped as true to make sure that loop runs
+ int gap = arr.length;
boolean swapped = true;
- // Keep running while gap is more than 1 and last iteration caused a swap
while (gap != 1 || swapped) {
- // Find next gap
- gap = nextGap(gap);
-
- // Initialize swapped as false so that we can check if swap happened or not
- swapped = false;
-
- // Compare all elements with current gap
- for (int i = 0; i < size - gap; i++) {
- if (SortUtils.less(arr[i + gap], arr[i])) {
- // Swap arr[i] and arr[i+gap]
- SortUtils.swap(arr, i, i + gap);
- swapped = true;
- }
- }
+ gap = getNextGap(gap);
+ swapped = performSwaps(arr, gap);
}
+
return arr;
}
- // Driver method
- public static void main(String[] args) {
- CombSort ob = new CombSort();
- Integer[] arr = {
- 8,
- 4,
- 1,
- 56,
- 3,
- -44,
- -1,
- 0,
- 36,
- 34,
- 8,
- 12,
- -66,
- -78,
- 23,
- -6,
- 28,
- 0,
- };
- ob.sort(arr);
+ /**
+ * Method to perform the swapping of elements in the array based on the current gap
+ *
+ * @param arr the array to be sorted
+ * @param gap the current gap
+ * @param the type of elements in the array
+ * @return true if a swap occurred, false otherwise
+ */
+ private > boolean performSwaps(final T[] arr, final int gap) {
+ boolean swapped = false;
+
+ for (int i = 0; i < arr.length - gap; i++) {
+ if (SortUtils.less(arr[i + gap], arr[i])) {
+ SortUtils.swap(arr, i, i + gap);
+ swapped = true;
+ }
+ }
- System.out.println("sorted array");
- SortUtils.print(arr);
+ return swapped;
}
}
diff --git a/src/test/java/com/thealgorithms/sorts/CombSortTest.java b/src/test/java/com/thealgorithms/sorts/CombSortTest.java
index e33fc388c1c5..6b70ffacda47 100644
--- a/src/test/java/com/thealgorithms/sorts/CombSortTest.java
+++ b/src/test/java/com/thealgorithms/sorts/CombSortTest.java
@@ -1,66 +1,8 @@
package com.thealgorithms.sorts;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-
-import org.junit.jupiter.api.Test;
-
-/**
- * @author Tabbygray (https://github.com/Tabbygray)
- * @see CombSort
- */
-
-public class CombSortTest {
-
- private CombSort combSort = new CombSort();
-
- @Test
- public void combSortEmptyArray() {
- Integer[] inputArray = {};
- Integer[] outputArray = combSort.sort(inputArray);
- Integer[] expectedOutput = {};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void combSortSingleStringElement() {
- String[] inputArray = {"Test"};
- String[] outputArray = combSort.sort(inputArray);
- String[] expectedArray = {"Test"};
- assertArrayEquals(outputArray, expectedArray);
- }
-
- @Test
- public void combSortStringArray() {
- String[] inputArray = {"4gp8", "aBJ2", "85cW", "Pmk9", "ewZO", "meuU", "RhNd", "5TKB", "eDd5", "zzyo"};
- String[] outputArray = combSort.sort(inputArray);
- String[] expectedArray = {"4gp8", "5TKB", "85cW", "Pmk9", "RhNd", "aBJ2", "eDd5", "ewZO", "meuU", "zzyo"};
- assertArrayEquals(outputArray, expectedArray);
- }
-
- @Test
- public void combSortIntegerArray() {
- Integer[] inputArray = {36, 98, -51, -23, 66, -58, 31, 25, -30, 40};
- Integer[] outputArray = combSort.sort(inputArray);
- Integer[] expectedArray = {-58, -51, -30, -23, 25, 31, 36, 40, 66, 98};
- assertArrayEquals(outputArray, expectedArray);
- }
-
- @Test
- public void combSortDoubleArray() {
- Double[] inputArray = {0.8335545399, 0.9346214114, 0.3096396752, 0.6433840668, 0.3973191975, 0.6118850724, 0.0553975453, 0.1961108601, 0.6172800885, 0.1065247772};
- Double[] outputArray = combSort.sort(inputArray);
- Double[] expectedArray = {
- 0.0553975453,
- 0.1065247772,
- 0.1961108601,
- 0.3096396752,
- 0.3973191975,
- 0.6118850724,
- 0.6172800885,
- 0.6433840668,
- 0.8335545399,
- 0.9346214114,
- };
- assertArrayEquals(outputArray, expectedArray);
+public class CombSortTest extends SortingAlgorithmTest {
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return new CombSort();
}
}
From 6f521145cce64822ac31331a33e48a9a748670c9 Mon Sep 17 00:00:00 2001
From: Bayram Turgut <137455737+bayramtturgutt@users.noreply.github.com>
Date: Sun, 4 Aug 2024 21:15:54 +0300
Subject: [PATCH 022/558] Update Average.java (#5309)
* Update Average.java
- Made the constructor throw an UnsupportedOperationException to prevent instantiation, making it explicit that this is a utility class.
- Added a private validateInput method to handle validation, reducing code duplication and improving readability.
- Consistent exception messages and handling for both methods.
- Improved comments to be more descriptive and follow JavaDoc conventions.
- Enhanced code readability and maintained consistent formatting.
* Minor Update Average.java
* Change To Average.java
* Mnr Average.java
* Update_Average.java
* Fix Average.java
1. throw new IllegalArgumentException("Numbers array cannot be empty or null");
2. int --> double
* fix2.java
return(double)..
---
.../java/com/thealgorithms/maths/Average.java | 26 ++++++++++++-------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/Average.java b/src/main/java/com/thealgorithms/maths/Average.java
index 1c632cf0a65e..6b9c20162da1 100644
--- a/src/main/java/com/thealgorithms/maths/Average.java
+++ b/src/main/java/com/thealgorithms/maths/Average.java
@@ -1,17 +1,23 @@
package com.thealgorithms.maths;
/**
- * Calculate average of a list of numbers
+ * A utility class for computing the average of numeric arrays.
+ * This class provides static methods to calculate the average of arrays
+ * of both {@code double} and {@code int} values.
*/
public final class Average {
+
+ // Prevent instantiation of this utility class
private Average() {
+ throw new UnsupportedOperationException("This is a utility class and cannot be instantiated.");
}
/**
- * Calculate average of a list of numbers
+ * Computes the average of a {@code double} array.
*
- * @param numbers array to store numbers
- * @return mean of given numbers
+ * @param numbers an array of {@code double} values
+ * @return the average of the given numbers
+ * @throws IllegalArgumentException if the input array is {@code null} or empty
*/
public static double average(double[] numbers) {
if (numbers == null || numbers.length == 0) {
@@ -25,13 +31,13 @@ public static double average(double[] numbers) {
}
/**
- * find average value of an int array
+ * Computes the average of an {@code int} array.
*
- * @param numbers the array contains element and the sum does not excess long
- * value limit
- * @return average value
+ * @param numbers an array of {@code int} values
+ * @return the average of the given numbers
+ * @throws IllegalArgumentException if the input array is {@code null} or empty
*/
- public static int average(int[] numbers) {
+ public static double average(int[] numbers) {
if (numbers == null || numbers.length == 0) {
throw new IllegalArgumentException("Numbers array cannot be empty or null");
}
@@ -39,6 +45,6 @@ public static int average(int[] numbers) {
for (int number : numbers) {
sum += number;
}
- return (int) (sum / numbers.length);
+ return (double) (sum / numbers.length);
}
}
From 365ede892f2a44ed11421887c06b65cd7a182cb3 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 8 Aug 2024 07:38:58 +0200
Subject: [PATCH 023/558] Chore(deps): bump org.apache.commons:commons-lang3
from 3.15.0 to 3.16.0 (#5312)
Bumps org.apache.commons:commons-lang3 from 3.15.0 to 3.16.0.
---
updated-dependencies:
- dependency-name: org.apache.commons:commons-lang3
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 0c01353aa5dd..0c69e1f50732 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,7 +50,7 @@
org.apache.commons
commons-lang3
- 3.15.0
+ 3.16.0
org.apache.commons
From 357e15adddd1c268909299345ca50bb63c1a982c Mon Sep 17 00:00:00 2001
From: Andrii Siriak
Date: Thu, 8 Aug 2024 09:55:11 +0300
Subject: [PATCH 024/558] Update CODEOWNERS
---
.github/CODEOWNERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index a84f13be1047..4f36c32c5157 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @yanglbme @vil02 @BamaCharanChhandogi
+* @yanglbme @vil02 @BamaCharanChhandogi @alxkm
From 6e23e198ab30bbba5cdbf74d5282f98080083f3d Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Thu, 8 Aug 2024 09:45:33 +0200
Subject: [PATCH 025/558] feat: `SpreadSort` implementation (#5308)
---
DIRECTORY.md | 2 +
.../com/thealgorithms/sorts/SpreadSort.java | 273 ++++++++++++++++++
.../thealgorithms/sorts/SpreadSortTest.java | 37 +++
3 files changed, 312 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/sorts/SpreadSort.java
create mode 100644 src/test/java/com/thealgorithms/sorts/SpreadSortTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 7e726f3191c6..22453235bfed 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -523,6 +523,7 @@
* [SortAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java)
* [SortUtils](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SortUtils.java)
* [SortUtilsRandomGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java)
+ * [SpreadSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SpreadSort.java)
* [StoogeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/StoogeSort.java)
* [StrandSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/StrandSort.java)
* [SwapSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SwapSort.java)
@@ -893,6 +894,7 @@
* [SortingAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java)
* [SortUtilsRandomGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java)
* [SortUtilsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java)
+ * [SpreadSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SpreadSortTest.java)
* [StoogeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/StoogeSortTest.java)
* [StrandSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/StrandSortTest.java)
* [SwapSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SwapSortTest.java)
diff --git a/src/main/java/com/thealgorithms/sorts/SpreadSort.java b/src/main/java/com/thealgorithms/sorts/SpreadSort.java
new file mode 100644
index 000000000000..f1fd24f4735d
--- /dev/null
+++ b/src/main/java/com/thealgorithms/sorts/SpreadSort.java
@@ -0,0 +1,273 @@
+package com.thealgorithms.sorts;
+import java.util.Arrays;
+
+/**
+ * SpreadSort is a highly efficient sorting algorithm suitable for large datasets.
+ * It distributes elements into buckets and recursively sorts these buckets.
+ * This implementation is generic and can sort any array of elements that extend Comparable.
+ */
+public class SpreadSort implements SortAlgorithm {
+ private static final int MAX_INSERTION_SORT_THRESHOLD = 1000;
+ private static final int MAX_INITIAL_BUCKET_CAPACITY = 1000;
+ private static final int MAX_MIN_BUCKETS = 100;
+
+ private final int insertionSortThreshold;
+ private final int initialBucketCapacity;
+ private final int minBuckets;
+
+ /**
+ * Constructor to initialize the SpreadSort algorithm with custom parameters.
+ *
+ * @param insertionSortThreshold the threshold for using insertion sort for small segments (1-1000)
+ * @param initialBucketCapacity the initial capacity for each bucket (1-1000)
+ * @param minBuckets the minimum number of buckets to use (1-100)
+ */
+ public SpreadSort(int insertionSortThreshold, int initialBucketCapacity, int minBuckets) {
+ if (insertionSortThreshold < 1 || insertionSortThreshold > MAX_INSERTION_SORT_THRESHOLD) {
+ throw new IllegalArgumentException("Insertion sort threshold must be between 1 and " + MAX_INSERTION_SORT_THRESHOLD);
+ }
+ if (initialBucketCapacity < 1 || initialBucketCapacity > MAX_INITIAL_BUCKET_CAPACITY) {
+ throw new IllegalArgumentException("Initial bucket capacity must be between 1 and " + MAX_INITIAL_BUCKET_CAPACITY);
+ }
+ if (minBuckets < 1 || minBuckets > MAX_MIN_BUCKETS) {
+ throw new IllegalArgumentException("Minimum number of buckets must be between 1 and " + MAX_MIN_BUCKETS);
+ }
+
+ this.insertionSortThreshold = insertionSortThreshold;
+ this.initialBucketCapacity = initialBucketCapacity;
+ this.minBuckets = minBuckets;
+ }
+
+ /**
+ * Default constructor with predefined values.
+ */
+ public SpreadSort() {
+ this(16, 16, 2);
+ }
+
+ /**
+ * Sorts an array using the SpreadSort 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) {
+ if (array.length == 0) {
+ return array;
+ }
+ spreadSort(array, 0, array.length - 1);
+ return array;
+ }
+
+ /**
+ * Internal method to sort an array segment using the SpreadSort algorithm.
+ *
+ * @param array the array to be sorted
+ * @param left the left boundary of the segment
+ * @param right the right boundary of the segment
+ * @param the type of elements in the array
+ */
+ private > void spreadSort(final T[] array, final int left, final int right) {
+ if (left >= right) {
+ return;
+ }
+
+ // Base case for small segments
+ if (right - left < insertionSortThreshold) {
+ insertionSort(array, left, right);
+ return;
+ }
+
+ T min = findMin(array, left, right);
+ T max = findMax(array, left, right);
+
+ if (min.equals(max)) {
+ return; // All elements are the same
+ }
+
+ int numBuckets = calculateNumBuckets(right - left + 1);
+ final Bucket[] buckets = createBuckets(numBuckets);
+
+ distributeElements(array, left, right, min, max, numBuckets, buckets);
+ collectElements(array, left, buckets);
+ }
+
+ /**
+ * Finds the minimum element in the specified segment of the array.
+ *
+ * @param array the array to search
+ * @param left the left boundary of the segment
+ * @param right the right boundary of the segment
+ * @param the type of elements in the array
+ * @return the minimum element
+ */
+ private > T findMin(final T[] array, final int left, final int right) {
+ T min = array[left];
+ for (int i = left + 1; i <= right; i++) {
+ if (SortUtils.less(array[i], min)) {
+ min = array[i];
+ }
+ }
+ return min;
+ }
+
+ /**
+ * Finds the maximum element in the specified segment of the array.
+ *
+ * @param array the array to search
+ * @param left the left boundary of the segment
+ * @param right the right boundary of the segment
+ * @param the type of elements in the array
+ * @return the maximum element
+ */
+ private > T findMax(final T[] array, final int left, final int right) {
+ T max = array[left];
+ for (int i = left + 1; i <= right; i++) {
+ if (SortUtils.greater(array[i], max)) {
+ max = array[i];
+ }
+ }
+ return max;
+ }
+
+ /**
+ * Calculates the number of buckets needed based on the size of the segment.
+ *
+ * @param segmentSize the size of the segment
+ * @return the number of buckets
+ */
+ private int calculateNumBuckets(final int segmentSize) {
+ int numBuckets = segmentSize / insertionSortThreshold;
+ return Math.max(numBuckets, minBuckets);
+ }
+
+ /**
+ * Creates an array of buckets.
+ *
+ * @param numBuckets the number of buckets to create
+ * @param the type of elements in the buckets
+ * @return an array of buckets
+ */
+ @SuppressWarnings("unchecked")
+ private > Bucket[] createBuckets(final int numBuckets) {
+ final Bucket[] buckets = new Bucket[numBuckets];
+ for (int i = 0; i < numBuckets; i++) {
+ buckets[i] = new Bucket<>(initialBucketCapacity);
+ }
+ return buckets;
+ }
+
+ /**
+ * Distributes elements of the array segment into buckets.
+ *
+ * @param array the array to be sorted
+ * @param left the left boundary of the segment
+ * @param right the right boundary of the segment
+ * @param min the minimum element in the segment
+ * @param max the maximum element in the segment
+ * @param numBuckets the number of buckets
+ * @param buckets the array of buckets
+ * @param the type of elements in the array
+ */
+ private > void distributeElements(final T[] array, final int left, final int right, final T min, final T max, final int numBuckets, final Bucket[] buckets) {
+ final double range = max.compareTo(min);
+ for (int i = left; i <= right; i++) {
+ final int scaleRangeDifference = array[i].compareTo(min) * numBuckets;
+ int bucketIndex = (int) (scaleRangeDifference / (range + 1));
+ buckets[bucketIndex].add(array[i]);
+ }
+ }
+
+ /**
+ * Collects elements from the buckets back into the array.
+ *
+ * @param array the array to be sorted
+ * @param left the left boundary of the segment
+ * @param buckets the array of buckets
+ * @param the type of elements in the array
+ */
+ private > void collectElements(final T[] array, final int left, final Bucket[] buckets) {
+ int index = left;
+ for (Bucket bucket : buckets) {
+ if (bucket.size() > 0) {
+ T[] bucketArray = bucket.toArray();
+ spreadSort(bucketArray, 0, bucketArray.length - 1);
+ for (T element : bucketArray) {
+ array[index++] = element;
+ }
+ }
+ }
+ }
+
+ /**
+ * Insertion sort implementation for small segments.
+ *
+ * @param array the array to be sorted
+ * @param left the left boundary of the segment
+ * @param right the right boundary of the segment
+ * @param the type of elements in the array
+ */
+ private > void insertionSort(final T[] array, final int left, final int right) {
+ for (int i = left + 1; i <= right; i++) {
+ T key = array[i];
+ int j = i - 1;
+ while (j >= left && SortUtils.greater(array[j], key)) {
+ array[j + 1] = array[j];
+ j--;
+ }
+ array[j + 1] = key;
+ }
+ }
+
+ /**
+ * Bucket class to hold elements during sorting.
+ *
+ * @param the type of elements in the bucket
+ */
+ private static class Bucket> {
+ private T[] elements;
+ private int size;
+
+ /**
+ * Constructs a new bucket with initial capacity.
+ */
+ @SuppressWarnings("unchecked")
+ Bucket(int initialBucketCapacity) {
+ elements = (T[]) new Comparable[initialBucketCapacity];
+ size = 0;
+ }
+
+ /**
+ * Adds an element to the bucket.
+ *
+ * @param element the element to add
+ */
+ void add(T element) {
+ if (size == elements.length) {
+ elements = Arrays.copyOf(elements, size * 2);
+ }
+ elements[size++] = element;
+ }
+
+ /**
+ * Returns the number of elements in the bucket.
+ *
+ * @return the size of the bucket
+ */
+ int size() {
+ return size;
+ }
+
+ /**
+ * Returns an array containing all elements in the bucket.
+ *
+ * @return an array containing all elements in the bucket
+ */
+ @SuppressWarnings("unchecked")
+ T[] toArray() {
+ return Arrays.copyOf(elements, size);
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/sorts/SpreadSortTest.java b/src/test/java/com/thealgorithms/sorts/SpreadSortTest.java
new file mode 100644
index 000000000000..a4992a02abfa
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/SpreadSortTest.java
@@ -0,0 +1,37 @@
+package com.thealgorithms.sorts;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.stream.Stream;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+
+public class SpreadSortTest extends SortingAlgorithmTest {
+
+ protected int getGeneratedArraySize() {
+ return 1000;
+ }
+
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return new SpreadSort();
+ }
+
+ static class ConstructorArgumentsProvider implements ArgumentsProvider {
+ @Override
+ public Stream extends Arguments> provideArguments(org.junit.jupiter.api.extension.ExtensionContext context) {
+ return Stream.of(Arguments.of(0, 16, 2, IllegalArgumentException.class), Arguments.of(16, 0, 2, IllegalArgumentException.class), Arguments.of(16, 16, 0, IllegalArgumentException.class), Arguments.of(1001, 16, 2, IllegalArgumentException.class),
+ Arguments.of(16, 1001, 2, IllegalArgumentException.class), Arguments.of(16, 16, 101, IllegalArgumentException.class));
+ }
+ }
+
+ @ParameterizedTest
+ @ArgumentsSource(ConstructorArgumentsProvider.class)
+ void testConstructor(int insertionSortThreshold, int initialBucketCapacity, int minBuckets, Class expectedException) {
+ Executable executable = () -> new SpreadSort(insertionSortThreshold, initialBucketCapacity, minBuckets);
+ assertThrows(expectedException, executable);
+ }
+}
From cafea1ee528bde4495024d7c8db177e9474e5e36 Mon Sep 17 00:00:00 2001
From: congyuluo <78986434+congyuluo@users.noreply.github.com>
Date: Thu, 8 Aug 2024 07:09:00 -0700
Subject: [PATCH 026/558] Refactored Identifiers (#5306)
Co-authored-by: Bama Charan Chhandogi
---
.../java/com/thealgorithms/misc/TwoSumProblem.java | 6 +++---
.../com/thealgorithms/searches/FibonacciSearch.java | 6 +++---
.../java/com/thealgorithms/strings/WordLadder.java | 10 +++++-----
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/main/java/com/thealgorithms/misc/TwoSumProblem.java b/src/main/java/com/thealgorithms/misc/TwoSumProblem.java
index ceeb3717fd4a..2fc4ed09a792 100644
--- a/src/main/java/com/thealgorithms/misc/TwoSumProblem.java
+++ b/src/main/java/com/thealgorithms/misc/TwoSumProblem.java
@@ -20,9 +20,9 @@ private TwoSumProblem() {
public static Optional> twoSum(final int[] values, final int target) {
HashMap valueToIndex = new HashMap<>();
for (int i = 0; i < values.length; i++) {
- final var rem = target - values[i];
- if (valueToIndex.containsKey(rem)) {
- return Optional.of(Pair.of(valueToIndex.get(rem), i));
+ final var remainder = target - values[i];
+ if (valueToIndex.containsKey(remainder)) {
+ return Optional.of(Pair.of(valueToIndex.get(remainder), i));
}
if (!valueToIndex.containsKey(values[i])) {
valueToIndex.put(values[i], i);
diff --git a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java
index 4fba6e257627..028ab07e0a86 100644
--- a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java
+++ b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java
@@ -62,10 +62,10 @@ public static void main(String[] args) {
Integer[] integers = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512};
int size = integers.length;
- Integer shouldBeFound = 128;
+ Integer targetValue = 128;
FibonacciSearch fsearch = new FibonacciSearch();
- int atIndex = fsearch.find(integers, shouldBeFound);
+ int atIndex = fsearch.find(integers, targetValue);
- System.out.println("Should be found: " + shouldBeFound + ". Found " + integers[atIndex] + " at index " + atIndex + ". An array length " + size);
+ System.out.println("Should be found: " + targetValue + ". Found " + integers[atIndex] + " at index " + atIndex + ". An array length " + size);
}
}
diff --git a/src/main/java/com/thealgorithms/strings/WordLadder.java b/src/main/java/com/thealgorithms/strings/WordLadder.java
index 16d4e0a02452..707fdfc67d85 100644
--- a/src/main/java/com/thealgorithms/strings/WordLadder.java
+++ b/src/main/java/com/thealgorithms/strings/WordLadder.java
@@ -75,13 +75,13 @@ public static int ladderLength(String beginWord, String endWord, List wo
continue;
}
wordsChars[j] = c;
- String newWord = String.valueOf(wordsChars);
- if (newWord.equals(endWord)) {
+ String transformedWord = String.valueOf(wordsChars);
+ if (transformedWord.equals(endWord)) {
return level + 1;
}
- if (set.contains(newWord)) {
- set.remove(newWord);
- queue.offer(newWord);
+ if (set.contains(transformedWord)) {
+ set.remove(transformedWord);
+ queue.offer(transformedWord);
}
}
wordsChars[j] = originalChars;
From 5fc26239eb2b6d93e582a8df30027d2ef3da392d Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 9 Aug 2024 07:42:26 +0200
Subject: [PATCH 027/558] Chore(deps): bump DoozyX/clang-format-lint-action
from 0.17 to 0.18 in /.github/workflows (#5313)
Chore(deps): bump DoozyX/clang-format-lint-action in /.github/workflows
Bumps [DoozyX/clang-format-lint-action](https://github.com/doozyx/clang-format-lint-action) from 0.17 to 0.18.
- [Release notes](https://github.com/doozyx/clang-format-lint-action/releases)
- [Commits](https://github.com/doozyx/clang-format-lint-action/compare/v0.17...v0.18)
---
updated-dependencies:
- dependency-name: DoozyX/clang-format-lint-action
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/clang-format-lint.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/clang-format-lint.yml b/.github/workflows/clang-format-lint.yml
index 7f3cb3d5162f..588c05e42e8f 100644
--- a/.github/workflows/clang-format-lint.yml
+++ b/.github/workflows/clang-format-lint.yml
@@ -9,7 +9,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- - uses: DoozyX/clang-format-lint-action@v0.17
+ - uses: DoozyX/clang-format-lint-action@v0.18
with:
source: './src'
extensions: 'java'
From 324a35a939e86eda64af74aad37c2d8536caed7f Mon Sep 17 00:00:00 2001
From: Bayram Turgut <137455737+bayramtturgutt@users.noreply.github.com>
Date: Fri, 9 Aug 2024 15:03:54 +0300
Subject: [PATCH 028/558] Update GrahamScan.java (#5310)
* Update GrahamScan.java
improved the Javadoc comments, clarified some methods in the Point class, and corrected some text.
* Minor adjustment to GrahamScan.java
* revised GrahamScan.java
* Update-2 GrahamScan.java
* clang format GrahamScan.java
* reverted GrahamScan.java
* minor updates.java
* minor updates
* Spc.java
* clang format
---------
Co-authored-by: Alex Klymenko
---
.../thealgorithms/geometry/GrahamScan.java | 117 ++++++++----------
1 file changed, 49 insertions(+), 68 deletions(-)
diff --git a/src/main/java/com/thealgorithms/geometry/GrahamScan.java b/src/main/java/com/thealgorithms/geometry/GrahamScan.java
index 2773d03b4769..1a36137895e0 100644
--- a/src/main/java/com/thealgorithms/geometry/GrahamScan.java
+++ b/src/main/java/com/thealgorithms/geometry/GrahamScan.java
@@ -1,56 +1,56 @@
package com.thealgorithms.geometry;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Stack;
-/*
- * A Java program that computes the convex hull using the Graham Scan algorithm
- * In the best case, time complexity is O(n), while in the worst case, it is O(nlog(n)).
- * O(n) space complexity
+/**
+ * A Java program that computes the convex hull using the Graham Scan algorithm.
+ * The time complexity is O(n) in the best case and O(n log(n)) in the worst case.
+ * The space complexity is O(n).
+ * This algorithm is applicable only to integral coordinates.
*
- * This algorithm is only applicable to integral coordinates.
- *
- * Reference:
+ * References:
* https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/graham_scan_algorithm.cpp
* https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/graham_scan_functions.hpp
* https://algs4.cs.princeton.edu/99hull/GrahamScan.java.html
*/
public class GrahamScan {
+
private final Stack hull = new Stack<>();
public GrahamScan(Point[] points) {
-
- /*
- * pre-process the points by sorting them with respect to the bottom-most point, then we'll
- * push the first point in the array to be our first extreme point.
- */
+ // Pre-process points: sort by y-coordinate, then by polar order with respect to the first point
Arrays.sort(points);
Arrays.sort(points, 1, points.length, points[0].polarOrder());
+
hull.push(points[0]);
- // find index of first point not equal to a[0] (indexPoint1) and the first point that's not
- // collinear with either (indexPoint2).
- int indexPoint1;
- for (indexPoint1 = 1; indexPoint1 < points.length; indexPoint1++) {
- if (!points[0].equals(points[indexPoint1])) {
+ // Find the first point not equal to points[0] (firstNonEqualIndex)
+ // and the first point not collinear firstNonCollinearIndex with the previous points
+ int firstNonEqualIndex;
+ for (firstNonEqualIndex = 1; firstNonEqualIndex < points.length; firstNonEqualIndex++) {
+ if (!points[0].equals(points[firstNonEqualIndex])) {
break;
}
}
- if (indexPoint1 == points.length) {
+
+ if (firstNonEqualIndex == points.length) {
return;
}
- int indexPoint2;
- for (indexPoint2 = indexPoint1 + 1; indexPoint2 < points.length; indexPoint2++) {
- if (Point.orientation(points[0], points[indexPoint1], points[indexPoint2]) != 0) {
+ int firstNonCollinearIndex;
+ for (firstNonCollinearIndex = firstNonEqualIndex + 1; firstNonCollinearIndex < points.length; firstNonCollinearIndex++) {
+ if (Point.orientation(points[0], points[firstNonEqualIndex], points[firstNonCollinearIndex]) != 0) {
break;
}
}
- hull.push(points[indexPoint2 - 1]);
- // Now we simply add the point to the stack based on the orientation.
- for (int i = indexPoint2; i < points.length; i++) {
+ hull.push(points[firstNonCollinearIndex - 1]);
+
+ // Process the remaining points and update the hull
+ for (int i = firstNonCollinearIndex; i < points.length; i++) {
Point top = hull.pop();
while (Point.orientation(hull.peek(), top, points[i]) <= 0) {
top = hull.pop();
@@ -61,14 +61,10 @@ public GrahamScan(Point[] points) {
}
/**
- * @return A stack of points representing the convex hull.
+ * @return An iterable collection of points representing the convex hull.
*/
public Iterable hull() {
- Stack s = new Stack<>();
- for (Point p : hull) {
- s.push(p);
- }
- return s;
+ return new ArrayList<>(hull);
}
public record Point(int x, int y) implements Comparable {
@@ -98,47 +94,41 @@ public int y() {
}
/**
- * Finds the orientation of ordered triplet.
+ * Determines the orientation of the triplet (a, b, c).
*
- * @param a Co-ordinates of point a
- * @param b Co-ordinates of point a
- * @param c Co-ordinates of point a
- * @return { -1, 0, +1 } if a -→ b -→ c is a { clockwise, collinear; counterclockwise }
- * turn.
+ * @param a The first point
+ * @param b The second point
+ * @param c The third point
+ * @return -1 if (a, b, c) is clockwise, 0 if collinear, +1 if counterclockwise
*/
public static int orientation(Point a, Point b, Point c) {
int val = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
- if (val == 0) {
- return 0;
- }
- return (val > 0) ? +1 : -1;
+ return Integer.compare(val, 0);
}
/**
- * @param p2 Co-ordinate of point to compare to.
- * This function will compare the points and will return a positive integer if the
- * point is greater than the argument point and a negative integer if the point is
- * less than the argument point.
+ * Compares this point with another point.
+ *
+ * @param p2 The point to compare to
+ * @return A positive integer if this point is greater, a negative integer if less, or 0 if equal
*/
+ @Override
public int compareTo(Point p2) {
- int res = Integer.compare(this.y, p2.y);
- if (res == 0) {
- res = Integer.compare(this.x, p2.x);
- }
- return res;
+ int cmpY = Integer.compare(this.y, p2.y);
+ return cmpY != 0 ? cmpY : Integer.compare(this.x, p2.x);
}
/**
- * A helper function that will let us sort points by their polar order
- * This function will compare the angle between 2 polar Co-ordinates
+ * Returns a comparator to sort points by their polar order relative to this point.
*
- * @return the comparator
+ * @return A polar order comparator
*/
public Comparator polarOrder() {
return new PolarOrder();
}
private final class PolarOrder implements Comparator {
+ @Override
public int compare(Point p1, Point p2) {
int dx1 = p1.x - x;
int dy1 = p1.y - y;
@@ -146,32 +136,23 @@ public int compare(Point p1, Point p2) {
int dy2 = p2.y - y;
if (dy1 >= 0 && dy2 < 0) {
- return -1; // q1 above; q2 below
+ return -1; // p1 above p2
} else if (dy2 >= 0 && dy1 < 0) {
- return +1; // q1 below; q2 above
- } else if (dy1 == 0 && dy2 == 0) { // 3-collinear and horizontal
- if (dx1 >= 0 && dx2 < 0) {
- return -1;
- } else if (dx2 >= 0 && dx1 < 0) {
- return +1;
- } else {
- return 0;
- }
+ return 1; // p1 below p2
+ } else if (dy1 == 0 && dy2 == 0) { // Collinear and horizontal
+ return Integer.compare(dx2, dx1);
} else {
- return -orientation(Point.this, p1, p2); // both above or below
+ return -orientation(Point.this, p1, p2); // Compare orientation
}
}
}
/**
- * Override of the toString method, necessary to compute the difference
- * between the expected result and the derived result
- *
- * @return a string representation of any given 2D point in the format (x, y)
+ * @return A string representation of this point in the format (x, y)
*/
@Override
public String toString() {
- return "(" + x + ", " + y + ")";
+ return String.format("(%d, %d)", x, y);
}
}
}
From 7a5fe92b2ac96d9a2e6e571285f3a188d7ea01ea Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Sat, 10 Aug 2024 09:25:46 +0200
Subject: [PATCH 029/558] feat: `FlashSort` implementation (#5305)
---
DIRECTORY.md | 2 +
.../com/thealgorithms/sorts/FlashSort.java | 206 ++++++++++++++++++
.../thealgorithms/sorts/FlashSortTest.java | 90 ++++++++
3 files changed, 298 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/sorts/FlashSort.java
create mode 100644 src/test/java/com/thealgorithms/sorts/FlashSortTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 22453235bfed..656597c3b20a 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -501,6 +501,7 @@
* [DualPivotQuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java)
* [DutchNationalFlagSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java)
* [ExchangeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/ExchangeSort.java)
+ * [FlashSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/FlashSort.java)
* [GnomeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/GnomeSort.java)
* [HeapSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/HeapSort.java)
* [InsertionSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/InsertionSort.java)
@@ -874,6 +875,7 @@
* [DualPivotQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java)
* [DutchNationalFlagSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java)
* [ExchangeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java)
+ * [FlashSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/FlashSortTest.java)
* [GnomeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java)
* [HeapSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/HeapSortTest.java)
* [InsertionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java)
diff --git a/src/main/java/com/thealgorithms/sorts/FlashSort.java b/src/main/java/com/thealgorithms/sorts/FlashSort.java
new file mode 100644
index 000000000000..e8dbf8c42742
--- /dev/null
+++ b/src/main/java/com/thealgorithms/sorts/FlashSort.java
@@ -0,0 +1,206 @@
+package com.thealgorithms.sorts;
+
+/**
+ * Implementation of Flash Sort algorithm that implements the SortAlgorithm interface.
+ *
+ * Sorts an array using the Flash Sort algorithm.
+ *
+ * Flash Sort is a distribution sorting algorithm that partitions the data into
+ * different classes based on a classification array. It performs the sorting by
+ * first distributing the data elements into different buckets (or classes) and
+ * then permuting these buckets into the sorted order.
+ *
+ * The method works as follows:
+ *
+ * - Finds the minimum and maximum values in the array.
+ * - Initializes a classification array `L` to keep track of the number of elements in each class.
+ * - Computes a normalization constant `c1` to map elements into classes.
+ * - Classifies each element of the array into the corresponding bucket in the classification array.
+ * - Transforms the classification array to compute the starting indices of each bucket.
+ * - Permutes the elements of the array into sorted order based on the classification.
+ * - Uses insertion sort for the final arrangement to ensure complete sorting.
+ *
+ */
+public class FlashSort implements SortAlgorithm {
+ private double classificationRatio = 0.45;
+
+ public FlashSort() {
+ }
+
+ public FlashSort(double classificationRatio) {
+ if (classificationRatio <= 0 || classificationRatio >= 1) {
+ throw new IllegalArgumentException("Classification ratio must be between 0 and 1 (exclusive).");
+ }
+ this.classificationRatio = classificationRatio;
+ }
+
+ public double getClassificationRatio() {
+ return classificationRatio;
+ }
+
+ public void setClassificationRatio(double classificationRatio) {
+ if (classificationRatio <= 0 || classificationRatio >= 1) {
+ throw new IllegalArgumentException("Classification ratio must be between 0 and 1 (exclusive).");
+ }
+ this.classificationRatio = classificationRatio;
+ }
+
+ /**
+ * Sorts an array using the Flash Sort algorithm.
+ *
+ * @param array the array to be sorted.
+ * @param the type of elements to be sorted, must be comparable.
+ * @return the sorted array.
+ */
+ @Override
+ public > T[] sort(T[] array) {
+ flashSort(array);
+ return array;
+ }
+
+ /**
+ * Sorts an array using the Flash Sort algorithm.
+ *
+ * @param arr the array to be sorted.
+ * @param the type of elements to be sorted, must be comparable.
+ */
+ private > void flashSort(T[] arr) {
+ if (arr.length == 0) {
+ return;
+ }
+
+ final T min = findMin(arr);
+ final int maxIndex = findMaxIndex(arr);
+
+ if (arr[maxIndex].compareTo(min) == 0) {
+ return; // All elements are the same
+ }
+
+ final int m = (int) (classificationRatio * arr.length);
+
+ final int[] classificationArray = new int[m];
+
+ final double c1 = (double) (m - 1) / arr[maxIndex].compareTo(min);
+
+ classify(arr, classificationArray, c1, min);
+
+ transform(classificationArray);
+
+ permute(arr, classificationArray, c1, min, arr.length, m);
+
+ insertionSort(arr);
+ }
+
+ /**
+ * Finds the minimum value in the array.
+ *
+ * @param arr the array to find the minimum value in.
+ * @param the type of elements in the array, must be comparable.
+ * @return the minimum value in the array.
+ */
+ private > T findMin(final T[] arr) {
+ T min = arr[0];
+ for (int i = 1; i < arr.length; i++) {
+ if (arr[i].compareTo(min) < 0) {
+ min = arr[i];
+ }
+ }
+ return min;
+ }
+
+ /**
+ * Finds the index of the maximum value in the array.
+ *
+ * @param arr the array to find the maximum value index in.
+ * @param the type of elements in the array, must be comparable.
+ * @return the index of the maximum value in the array.
+ */
+ private > int findMaxIndex(final T[] arr) {
+ int maxIndex = 0;
+ for (int i = 1; i < arr.length; i++) {
+ if (arr[i].compareTo(arr[maxIndex]) > 0) {
+ maxIndex = i;
+ }
+ }
+ return maxIndex;
+ }
+
+ /**
+ * Classifies elements of the array into the classification array classificationArray.
+ *
+ * @param arr the array to be classified.
+ * @param classificationArray the classification array holding the count of elements in each class.
+ * @param c1 the normalization constant used to map the elements to the classification array.
+ * @param min the minimum value in the array.
+ * @param the type of elements in the array, must be comparable.
+ */
+ private > void classify(final T[] arr, final int[] classificationArray, final double c1, final T min) {
+ for (int i = 0; i < arr.length; i++) {
+ int k = (int) (c1 * arr[i].compareTo(min));
+ classificationArray[k]++;
+ }
+ }
+
+ /**
+ * Transforms the classification array classificationArray into the starting index array.
+ *
+ * @param classificationArray the classification array holding the count of elements in each class.
+ */
+ private void transform(final int[] classificationArray) {
+ for (int i = 1; i < classificationArray.length; i++) {
+ classificationArray[i] += classificationArray[i - 1];
+ }
+ }
+
+ /**
+ * Permutes the array into sorted order based on the classification array classificationArray.
+ *
+ * @param arr the array to be permuted.
+ * @param classificationArray the classification array holding the count of elements in each class.
+ * @param c1 the normalization constant used to map the elements to the classification array.
+ * @param min the minimum value in the array.
+ * @param n the length of the array.
+ * @param m the number of classes in the classification array.
+ * @param the type of elements in the array, must be comparable.
+ */
+ private > void permute(final T[] arr, final int[] classificationArray, final double c1, T min, int n, int m) {
+ int move = 0;
+ int j = 0;
+ int k = m - 1;
+ T flash;
+ while (move < n - 1) {
+ while (j > classificationArray[k] - 1) {
+ j++;
+ k = (int) (c1 * arr[j].compareTo(min));
+ }
+ flash = arr[j];
+ while (j != classificationArray[k]) {
+ k = (int) (c1 * flash.compareTo(min));
+ T temp = arr[classificationArray[k] - 1];
+ arr[classificationArray[k] - 1] = flash;
+ flash = temp;
+ classificationArray[k]--;
+ move++;
+ }
+ }
+ }
+
+ /**
+ * Sorts an array using the insertion sort algorithm.
+ *
+ * @param arr the array to be sorted.
+ * @param the type of elements to be sorted, must be comparable.
+ */
+ private > void insertionSort(final T[] arr) {
+ int n = arr.length;
+ for (int i = 1; i < n; i++) {
+ T key = arr[i];
+ int j = i - 1;
+ while (j >= 0 && arr[j].compareTo(key) > 0) {
+ arr[j + 1] = arr[j];
+ j--;
+ }
+ arr[j + 1] = key;
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/sorts/FlashSortTest.java b/src/test/java/com/thealgorithms/sorts/FlashSortTest.java
new file mode 100644
index 000000000000..6b1a74403a59
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/FlashSortTest.java
@@ -0,0 +1,90 @@
+package com.thealgorithms.sorts;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestFactory;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+public class FlashSortTest extends SortingAlgorithmTest {
+ private final FlashSort flashSort = new FlashSort();
+
+ public FlashSort getFlashSort() {
+ return flashSort;
+ }
+
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return getFlashSort();
+ }
+
+ @Test
+ public void testDefaultConstructor() {
+ double defaultRation = 0.45;
+ FlashSort sorter = new FlashSort();
+ assertEquals(defaultRation, sorter.getClassificationRatio());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = {0.1, 0.2, 0.5, 0.9})
+ public void testCustomConstructorValidRatio(double ratio) {
+ FlashSort sorter = new FlashSort(ratio);
+ assertEquals(ratio, sorter.getClassificationRatio());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = {0, 1, -0.1, 1.1})
+ public void testCustomConstructorInvalidRatio(double ratio) {
+ assertThrows(IllegalArgumentException.class, () -> new FlashSort(ratio));
+ }
+
+ @TestFactory
+ public Collection dynamicTestsForSorting() {
+ List dynamicTests = new ArrayList<>();
+ double[] ratios = {0.1, 0.2, 0.5, 0.9};
+
+ for (double ratio : ratios) {
+ FlashSort sorter = (FlashSort) getSortAlgorithm();
+ sorter.setClassificationRatio(ratio);
+ dynamicTests.addAll(createDynamicTestsForRatio(ratio));
+ }
+
+ return dynamicTests;
+ }
+
+ private Collection createDynamicTestsForRatio(double ratio) {
+ List dynamicTests = new ArrayList<>();
+ for (TestMethod testMethod : getTestMethodsFromSuperClass()) {
+ dynamicTests.add(DynamicTest.dynamicTest("Ratio: " + ratio + " - Test: " + testMethod.name(), testMethod.executable()));
+ }
+ return dynamicTests;
+ }
+
+ private List getTestMethodsFromSuperClass() {
+ List testMethods = new ArrayList<>();
+ Method[] methods = SortingAlgorithmTest.class.getDeclaredMethods();
+ for (Method method : methods) {
+ if (method.isAnnotationPresent(Test.class)) {
+ testMethods.add(new TestMethod(() -> {
+ try {
+ method.invoke(this);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }, method.getName()));
+ }
+ }
+ return testMethods;
+ }
+
+ record TestMethod(Executable executable, String name) {
+ }
+}
From 197718842f382ff83deb5d8f24fe541e0afd1025 Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Sat, 10 Aug 2024 13:21:44 +0200
Subject: [PATCH 030/558] refactor: cleanup `BucketSort` (#5314)
---
.../com/thealgorithms/sorts/BucketSort.java | 163 ++++++++++--------
.../thealgorithms/sorts/BucketSortTest.java | 48 +-----
2 files changed, 91 insertions(+), 120 deletions(-)
diff --git a/src/main/java/com/thealgorithms/sorts/BucketSort.java b/src/main/java/com/thealgorithms/sorts/BucketSort.java
index 2a48cca0f433..a6901ac339ac 100644
--- a/src/main/java/com/thealgorithms/sorts/BucketSort.java
+++ b/src/main/java/com/thealgorithms/sorts/BucketSort.java
@@ -3,117 +3,128 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Random;
/**
- * Wikipedia: https://en.wikipedia.org/wiki/Bucket_sort
+ * BucketSort class provides a method to sort an array of elements using the Bucket Sort algorithm
+ * and implements the SortAlgorithm interface.
*/
-public final class BucketSort {
- private BucketSort() {
- }
+public class BucketSort implements SortAlgorithm {
- public static void main(String[] args) {
- int[] arr = new int[10];
+ // Constant that defines the divisor for determining the number of buckets
+ private static final int BUCKET_DIVISOR = 10;
- /* generate 10 random numbers from -50 to 49 */
- Random random = new Random();
- for (int i = 0; i < arr.length; ++i) {
- arr[i] = random.nextInt(100) - 50;
+ @Override
+ public > T[] sort(T[] array) {
+ if (array.length == 0) {
+ return array;
}
- bucketSort(arr);
+ T min = findMin(array);
+ T max = findMax(array);
+ int numberOfBuckets = calculateNumberOfBuckets(array.length);
- /* check array is sorted or not */
- for (int i = 0, limit = arr.length - 1; i < limit; ++i) {
- assert arr[i] <= arr[i + 1];
- }
+ List> buckets = initializeBuckets(numberOfBuckets);
+ distributeElementsIntoBuckets(array, buckets, min, max, numberOfBuckets);
+
+ return concatenateBuckets(buckets, array);
}
/**
- * BucketSort algorithms implements
+ * Calculates the number of buckets to use based on the size of the array.
*
- * @param arr the array contains elements
+ * @param arrayLength the length of the array
+ * @return the number of buckets
*/
- public static int[] bucketSort(int[] arr) {
- /* get max value of arr */
- int max = max(arr);
-
- /* get min value of arr */
- int min = min(arr);
-
- /* number of buckets */
- int numberOfBuckets = max - min + 1;
-
- List> buckets = new ArrayList<>(numberOfBuckets);
+ private int calculateNumberOfBuckets(final int arrayLength) {
+ return Math.max(arrayLength / BUCKET_DIVISOR, 1);
+ }
- /* init buckets */
- for (int i = 0; i < numberOfBuckets; ++i) {
+ /**
+ * 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<>());
}
-
- /* store elements to buckets */
- for (int value : arr) {
- int hash = hash(value, min, numberOfBuckets);
- buckets.get(hash).add(value);
- }
-
- /* sort individual bucket */
- for (List bucket : buckets) {
- Collections.sort(bucket);
- }
-
- /* concatenate buckets to origin array */
- int index = 0;
- for (List bucket : buckets) {
- for (int value : bucket) {
- arr[index++] = value;
- }
- }
-
- return arr;
+ return buckets;
}
/**
- * Get index of bucket which of our elements gets placed into it.
+ * Distributes elements from the array into the appropriate buckets.
*
- * @param elem the element of array to be sorted
- * @param min min value of array
- * @param numberOfBucket the number of bucket
- * @return index of bucket
+ * @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 static int hash(int elem, int min, int numberOfBucket) {
- return (elem - min) / numberOfBucket;
+ 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);
+ }
}
/**
- * Calculate max value of array
+ * Concatenates the sorted buckets back into the original array.
*
- * @param arr the array contains elements
- * @return max value of given 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
*/
- public static int max(int[] arr) {
- int max = arr[0];
- for (int value : arr) {
- if (value > max) {
- max = value;
+ private > T[] concatenateBuckets(List> buckets, T[] array) {
+ int index = 0;
+ for (List bucket : buckets) {
+ Collections.sort(bucket);
+ for (T element : bucket) {
+ array[index++] = element;
}
}
- return max;
+ return array;
}
/**
- * Calculate min value of 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 arr the array contains elements
- * @return min value of given array
+ * @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
*/
- public static int min(int[] arr) {
- int min = arr[0];
- for (int value : arr) {
- if (value < min) {
- min = value;
+ 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 findMax(T[] array) {
+ T max = array[0];
+ for (T element : array) {
+ if (element.compareTo(max) > 0) {
+ max = element;
+ }
+ }
+ return max;
+ }
}
diff --git a/src/test/java/com/thealgorithms/sorts/BucketSortTest.java b/src/test/java/com/thealgorithms/sorts/BucketSortTest.java
index bd9d2e3d60cf..a2dcb8cadfd9 100644
--- a/src/test/java/com/thealgorithms/sorts/BucketSortTest.java
+++ b/src/test/java/com/thealgorithms/sorts/BucketSortTest.java
@@ -1,48 +1,8 @@
package com.thealgorithms.sorts;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-
-import org.junit.jupiter.api.Test;
-
-public class BucketSortTest {
-
- @Test
- public void bucketSortSingleIntegerArray() {
- int[] inputArray = {4};
- int[] outputArray = BucketSort.bucketSort(inputArray);
- int[] expectedOutput = {4};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void bucketSortNonDuplicateIntegerArray() {
- int[] inputArray = {6, 1, 99, 27, 15, 23, 36};
- int[] outputArray = BucketSort.bucketSort(inputArray);
- int[] expectedOutput = {1, 6, 15, 23, 27, 36, 99};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void bucketSortDuplicateIntegerArray() {
- int[] inputArray = {6, 1, 27, 15, 23, 27, 36, 23};
- int[] outputArray = BucketSort.bucketSort(inputArray);
- int[] expectedOutput = {1, 6, 15, 23, 23, 27, 27, 36};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void bucketSortNonDuplicateIntegerArrayWithNegativeNum() {
- int[] inputArray = {6, -1, 99, 27, -15, 23, -36};
- int[] outputArray = BucketSort.bucketSort(inputArray);
- int[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99};
- assertArrayEquals(outputArray, expectedOutput);
- }
-
- @Test
- public void bucketSortDuplicateIntegerArrayWithNegativeNum() {
- int[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23};
- int[] outputArray = BucketSort.bucketSort(inputArray);
- int[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27};
- assertArrayEquals(outputArray, expectedOutput);
+public class BucketSortTest extends SortingAlgorithmTest {
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return new BucketSort();
}
}
From 554b6cf0062b83dab5375adc49178eec1f266276 Mon Sep 17 00:00:00 2001
From: Alex Klymenko
Date: Sun, 11 Aug 2024 19:44:22 +0200
Subject: [PATCH 031/558] refactor: simple improvements and cleanup for
different sorts (#5318)
---
.../sorts/DutchNationalFlagSort.java | 22 ++++----
.../com/thealgorithms/sorts/GnomeSort.java | 53 ++-----------------
.../com/thealgorithms/sorts/HeapSort.java | 4 +-
.../com/thealgorithms/sorts/QuickSort.java | 12 ++---
.../sorts/SelectionSortRecursive.java | 4 +-
.../com/thealgorithms/sorts/StoogeSort.java | 24 ++++-----
.../com/thealgorithms/sorts/StrandSort.java | 8 +--
.../com/thealgorithms/sorts/SwapSort.java | 7 ++-
.../java/com/thealgorithms/sorts/TimSort.java | 12 ++---
9 files changed, 51 insertions(+), 95 deletions(-)
diff --git a/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java b/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java
index 20b8f0ba1abc..abfcb452b29a 100644
--- a/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java
+++ b/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java
@@ -12,31 +12,31 @@
public class DutchNationalFlagSort implements SortAlgorithm {
@Override
- public > T[] sort(T[] unsorted) {
- return dutchNationalFlagSort(unsorted, unsorted[(int) Math.ceil((unsorted.length) / 2.0) - 1]);
+ public > T[] sort(T[] array) {
+ return dutchNationalFlagSort(array, array[(int) Math.ceil((array.length) / 2.0) - 1]);
}
- public > T[] sort(T[] unsorted, T intendedMiddle) {
- return dutchNationalFlagSort(unsorted, intendedMiddle);
+ public > T[] sort(T[] array, T intendedMiddle) {
+ return dutchNationalFlagSort(array, intendedMiddle);
}
- private > T[] dutchNationalFlagSort(T[] arr, T intendedMiddle) {
+ private > T[] dutchNationalFlagSort(final T[] array, final T intendedMiddle) {
int i = 0;
int j = 0;
- int k = arr.length - 1;
+ int k = array.length - 1;
while (j <= k) {
- if (0 > arr[j].compareTo(intendedMiddle)) {
- SortUtils.swap(arr, i, j);
+ if (0 > array[j].compareTo(intendedMiddle)) {
+ SortUtils.swap(array, i, j);
j++;
i++;
- } else if (0 < arr[j].compareTo(intendedMiddle)) {
- SortUtils.swap(arr, j, k);
+ } else if (0 < array[j].compareTo(intendedMiddle)) {
+ SortUtils.swap(array, j, k);
k--;
} else {
j++;
}
}
- return arr;
+ return array;
}
}
diff --git a/src/main/java/com/thealgorithms/sorts/GnomeSort.java b/src/main/java/com/thealgorithms/sorts/GnomeSort.java
index 9bef6a2837b5..b074c271404d 100644
--- a/src/main/java/com/thealgorithms/sorts/GnomeSort.java
+++ b/src/main/java/com/thealgorithms/sorts/GnomeSort.java
@@ -9,63 +9,20 @@
public class GnomeSort implements SortAlgorithm {
@Override
- public > T[] sort(T[] arr) {
+ public > T[] sort(final T[] array) {
int i = 1;
int j = 2;
- while (i < arr.length) {
- if (SortUtils.less(arr[i - 1], arr[i])) {
+ while (i < array.length) {
+ if (SortUtils.less(array[i - 1], array[i])) {
i = j++;
} else {
- SortUtils.swap(arr, i - 1, i);
+ SortUtils.swap(array, i - 1, i);
if (--i == 0) {
i = j++;
}
}
}
- return null;
- }
-
- public static void main(String[] args) {
- Integer[] integers = {
- 4,
- 23,
- 6,
- 78,
- 1,
- 26,
- 11,
- 23,
- 0,
- -6,
- 3,
- 54,
- 231,
- 9,
- 12,
- };
- String[] strings = {
- "c",
- "a",
- "e",
- "b",
- "d",
- "dd",
- "da",
- "zz",
- "AA",
- "aa",
- "aB",
- "Hb",
- "Z",
- };
- GnomeSort gnomeSort = new GnomeSort();
-
- gnomeSort.sort(integers);
- gnomeSort.sort(strings);
-
- System.out.println("After sort : ");
- SortUtils.print(integers);
- SortUtils.print(strings);
+ return array;
}
}
diff --git a/src/main/java/com/thealgorithms/sorts/HeapSort.java b/src/main/java/com/thealgorithms/sorts/HeapSort.java
index 91d556b17b16..e798fb91b925 100644
--- a/src/main/java/com/thealgorithms/sorts/HeapSort.java
+++ b/src/main/java/com/thealgorithms/sorts/HeapSort.java
@@ -25,13 +25,13 @@ public > T[] sort(T[] array) {
return array;
}
- private static