Skip to content

Commit 2d6c39c

Browse files
alxkmAlex Klymenkovil02
authored
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 <[email protected]> Co-authored-by: Piotr Idzik <[email protected]>
1 parent 87e6184 commit 2d6c39c

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

DIRECTORY.md

+2
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@
494494
* [BucketSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BucketSort.java)
495495
* [CircleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CircleSort.java)
496496
* [CocktailShakerSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java)
497+
* [CountingSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CountingSort.java)
497498
* [CombSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CombSort.java)
498499
* [CycleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CycleSort.java)
499500
* [DNFSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DNFSort.java)
@@ -862,6 +863,7 @@
862863
* [BucketSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BucketSortTest.java)
863864
* [CircleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CircleSortTest.java)
864865
* [CocktailShakerSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java)
866+
* [CountingSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CountingSortTest.java)
865867
* [CombSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CombSortTest.java)
866868
* [DualPivotQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java)
867869
* [DutchNationalFlagSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.thealgorithms.sorts;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* A standard implementation of the Counting Sort algorithm for integer arrays.
7+
* This implementation has a time complexity of O(n + k), where n is the number
8+
* of elements in the input array and k is the range of the input.
9+
* It works only with integer arrays.
10+
*
11+
* The space complexity is O(k), where k is the range of the input integers.
12+
*
13+
* Note: This implementation handles negative integers as it
14+
* calculates the range based on the minimum and maximum values of the array.
15+
*
16+
*/
17+
public final class CountingSort {
18+
private CountingSort() {
19+
}
20+
21+
/**
22+
* Sorts an array of integers using the Counting Sort algorithm.
23+
*
24+
* @param array the array to be sorted
25+
* @return the sorted array
26+
*/
27+
public static int[] sort(int[] array) {
28+
if (array.length == 0) {
29+
return array;
30+
}
31+
final var stats = Arrays.stream(array).summaryStatistics();
32+
final int min = stats.getMin();
33+
int[] count = computeHistogram(array, min, stats.getMax() - min + 1);
34+
toCumulative(count);
35+
return reconstructSorted(count, min, array);
36+
}
37+
38+
private static int[] computeHistogram(final int[] array, final int shift, final int spread) {
39+
int[] res = new int[spread];
40+
for (final var value : array) {
41+
res[value - shift]++;
42+
}
43+
return res;
44+
}
45+
46+
private static void toCumulative(int[] count) {
47+
for (int i = 1; i < count.length; i++) {
48+
count[i] += count[i - 1];
49+
}
50+
}
51+
52+
private static int[] reconstructSorted(final int[] cumulativeCount, final int shift, final int[] array) {
53+
int[] res = new int[array.length];
54+
for (int i = array.length - 1; i >= 0; i--) {
55+
res[cumulativeCount[array[i] - shift] - 1] = array[i];
56+
cumulativeCount[array[i] - shift]--;
57+
}
58+
return res;
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.thealgorithms.sorts;
2+
3+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4+
5+
import java.util.stream.Stream;
6+
import org.junit.jupiter.params.ParameterizedTest;
7+
import org.junit.jupiter.params.provider.MethodSource;
8+
9+
public class CountingSortTest {
10+
11+
record TestCase(int[] inputArray, int[] expectedArray) {
12+
}
13+
14+
static Stream<TestCase> provideTestCases() {
15+
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}),
16+
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}),
17+
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}),
18+
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}));
19+
}
20+
21+
@ParameterizedTest
22+
@MethodSource("provideTestCases")
23+
public void testCountingSortException(TestCase testCase) {
24+
int[] outputArray = CountingSort.sort(testCase.inputArray);
25+
assertArrayEquals(testCase.expectedArray, outputArray);
26+
}
27+
}

0 commit comments

Comments
 (0)