From 5a3a8fd50c844d7a6e1c0100107046d98f7b9c2e Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Wed, 3 Jul 2024 19:36:13 +0200 Subject: [PATCH 01/10] refactor: cleanup counting sort --- DIRECTORY.md | 1 + .../com/thealgorithms/sorts/CountingSort.java | 86 +++++-------------- .../sorts/CountingSortUsingStream.java | 27 ++++++ .../thealgorithms/sorts/CountingSortTest.java | 8 ++ .../sorts/CountingSortUsingStreamTest.java | 8 ++ 5 files changed, 65 insertions(+), 65 deletions(-) create mode 100644 src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java create mode 100644 src/test/java/com/thealgorithms/sorts/CountingSortTest.java create mode 100644 src/test/java/com/thealgorithms/sorts/CountingSortUsingStreamTest.java diff --git a/DIRECTORY.md b/DIRECTORY.md index 6cecfef02de5..371c3caa4b10 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -496,6 +496,7 @@ * [CocktailShakerSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.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) + * [CountingSortUsingStream](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.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) diff --git a/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/CountingSort.java index e83271d9ee67..d12f7f667803 100644 --- a/src/main/java/com/thealgorithms/sorts/CountingSort.java +++ b/src/main/java/com/thealgorithms/sorts/CountingSort.java @@ -1,93 +1,49 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.print; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.TreeMap; -import java.util.stream.IntStream; -import java.util.stream.Stream; /** + * CountingSort is a generic implementation of the counting sort algorithm. + * This implementation sorts elements that implement the Comparable interface. + * * @author Youssef Ali (https://github.com/youssefAli11997) * @author Podshivalov Nikita (https://github.com/nikitap492) */ class CountingSort implements SortAlgorithm { - @Override - public > T[] sort(T[] unsorted) { - return sort(Arrays.asList(unsorted)).toArray(unsorted); + public > T[] sort(T[] array) { + return sort(Arrays.asList(array)).toArray(array); } /** - * This method implements the Generic Counting Sort + * Sorts the provided list using the counting sort algorithm. * - * @param list The list to be sorted - *

- * Sorts the list in increasing order The method uses list elements as keys - * in the frequency map + * @param list The list to be sorted. + * @param The type of elements in the list, must be Comparable. + * @return A sorted list in increasing order. */ @Override public > List sort(List list) { - Map frequency = new TreeMap<>(); - // The final output array - List sortedArray = new ArrayList<>(list.size()); + // TreeMap to maintain order of elements naturally. + Map frequencyMap = new TreeMap<>(); - // Counting the frequency of @param array elements - list.forEach(v -> frequency.put(v, frequency.getOrDefault(v, 0) + 1)); + // Count the frequency of each element in the list. + for (T element : list) { + frequencyMap.put(element, frequencyMap.getOrDefault(element, 0) + 1); + } - // Filling the sortedArray - for (Map.Entry element : frequency.entrySet()) { - for (int j = 0; j < element.getValue(); j++) { - sortedArray.add(element.getKey()); + // Create the sorted list based on the frequency map. + List sortedList = new ArrayList<>(list.size()); + for (Map.Entry entry : frequencyMap.entrySet()) { + for (int i = 0; i < entry.getValue(); i++) { + sortedList.add(entry.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)); + return sortedList; } } diff --git a/src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java b/src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java new file mode 100644 index 000000000000..88793da2682f --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java @@ -0,0 +1,27 @@ +package com.thealgorithms.sorts; + +import java.util.Arrays; +import java.util.List; +import java.util.TreeMap; +import java.util.stream.IntStream; + +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; + +public class CountingSortUsingStream implements SortAlgorithm { + @Override + public > T[] sort(T[] array) { + return streamSort(Arrays.asList(array)).toArray(array); + } + + /** + * Sorts the provided list using the counting sort algorithm with the Stream API. + * + * @param list The list to be sorted. + * @param The type of elements in the list, must be Comparable. + * @return A sorted list in increasing order. + */ + private static > List streamSort(List list) { + return list.stream().collect(toMap(k -> k, v -> 1, Integer::sum, TreeMap::new)).entrySet().stream().flatMap(entry -> IntStream.rangeClosed(1, entry.getValue()).mapToObj(t -> entry.getKey())).collect(toList()); + } +} 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..186ffc9c5ce3 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/CountingSortTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +public class CountingSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new CountingSort(); + } +} diff --git a/src/test/java/com/thealgorithms/sorts/CountingSortUsingStreamTest.java b/src/test/java/com/thealgorithms/sorts/CountingSortUsingStreamTest.java new file mode 100644 index 000000000000..39cf216c5987 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/CountingSortUsingStreamTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +public class CountingSortUsingStreamTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new CountingSortUsingStream(); + } +} From d0fb1ba483f0dd0b11a4d705943eb93e2324d923 Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Wed, 3 Jul 2024 19:42:06 +0200 Subject: [PATCH 02/10] checkstyle: fix import, adding links --- DIRECTORY.md | 2 ++ .../com/thealgorithms/sorts/CountingSortUsingStream.java | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 371c3caa4b10..f6b63d737773 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -865,6 +865,8 @@ * [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) * [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) + * [CountingSortUsingStream](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CountingSortUsingStream.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/CountingSortUsingStream.java b/src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java index 88793da2682f..405055793890 100644 --- a/src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java +++ b/src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java @@ -1,13 +1,13 @@ package com.thealgorithms.sorts; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; + import java.util.Arrays; import java.util.List; import java.util.TreeMap; import java.util.stream.IntStream; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; - public class CountingSortUsingStream implements SortAlgorithm { @Override public > T[] sort(T[] array) { From d070a545b4829d38e05ac416bfab0c04d24877c9 Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Fri, 5 Jul 2024 20:34:32 +0200 Subject: [PATCH 03/10] fix: extracting logic to separate methods to improve readability --- .../com/thealgorithms/sorts/CountingSort.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/CountingSort.java index d12f7f667803..ee893008f13f 100644 --- a/src/main/java/com/thealgorithms/sorts/CountingSort.java +++ b/src/main/java/com/thealgorithms/sorts/CountingSort.java @@ -28,22 +28,26 @@ public > T[] sort(T[] array) { */ @Override public > List sort(List list) { - // TreeMap to maintain order of elements naturally. - Map frequencyMap = new TreeMap<>(); - - // Count the frequency of each element in the list. - for (T element : list) { - frequencyMap.put(element, frequencyMap.getOrDefault(element, 0) + 1); - } + Map frequencyMap = computeHistogramMap(list); + return formSortedArrayFromHistogramMap(list, frequencyMap); + } - // Create the sorted list based on the frequency map. + private static > List formSortedArrayFromHistogramMap(List list, Map frequencyMap) { List sortedList = new ArrayList<>(list.size()); for (Map.Entry entry : frequencyMap.entrySet()) { for (int i = 0; i < entry.getValue(); i++) { sortedList.add(entry.getKey()); } } - return sortedList; } + + private static > Map computeHistogramMap(List list) { + // TreeMap to maintain order of elements naturally. + Map frequencyMap = new TreeMap<>(); + for (T element : list) { + frequencyMap.put(element, frequencyMap.getOrDefault(element, 0) + 1); + } + return frequencyMap; + } } From 6e0e04494e86a3481f974aab15a748c452876f04 Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Fri, 5 Jul 2024 20:36:45 +0200 Subject: [PATCH 04/10] fix: change name from histogram to frequency --- src/main/java/com/thealgorithms/sorts/CountingSort.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/CountingSort.java index ee893008f13f..35349ff1b7eb 100644 --- a/src/main/java/com/thealgorithms/sorts/CountingSort.java +++ b/src/main/java/com/thealgorithms/sorts/CountingSort.java @@ -28,11 +28,11 @@ public > T[] sort(T[] array) { */ @Override public > List sort(List list) { - Map frequencyMap = computeHistogramMap(list); - return formSortedArrayFromHistogramMap(list, frequencyMap); + Map frequencyMap = computeFequencyMap(list); + return formSortedArrayFromFrequencyMap(list, frequencyMap); } - private static > List formSortedArrayFromHistogramMap(List list, Map frequencyMap) { + private static > List formSortedArrayFromFrequencyMap(List list, Map frequencyMap) { List sortedList = new ArrayList<>(list.size()); for (Map.Entry entry : frequencyMap.entrySet()) { for (int i = 0; i < entry.getValue(); i++) { @@ -42,7 +42,7 @@ private static > List formSortedArrayFromHistogramMap return sortedList; } - private static > Map computeHistogramMap(List list) { + private static > Map computeFequencyMap(List list) { // TreeMap to maintain order of elements naturally. Map frequencyMap = new TreeMap<>(); for (T element : list) { From 0e43795e2c66dd6728bc702c5ec7519156da5b78 Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Fri, 5 Jul 2024 20:39:01 +0200 Subject: [PATCH 05/10] fix: improve naming --- src/main/java/com/thealgorithms/sorts/CountingSort.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/CountingSort.java index 35349ff1b7eb..a7b2f0af4181 100644 --- a/src/main/java/com/thealgorithms/sorts/CountingSort.java +++ b/src/main/java/com/thealgorithms/sorts/CountingSort.java @@ -29,11 +29,11 @@ public > T[] sort(T[] array) { @Override public > List sort(List list) { Map frequencyMap = computeFequencyMap(list); - return formSortedArrayFromFrequencyMap(list, frequencyMap); + return extractSortedArray(frequencyMap); } - private static > List formSortedArrayFromFrequencyMap(List list, Map frequencyMap) { - List sortedList = new ArrayList<>(list.size()); + private static > List extractSortedArray(Map frequencyMap) { + List sortedList = new ArrayList<>(); for (Map.Entry entry : frequencyMap.entrySet()) { for (int i = 0; i < entry.getValue(); i++) { sortedList.add(entry.getKey()); From 2ea5f559b0913fde0ff3b3a235276ed9409c4b08 Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Fri, 5 Jul 2024 22:42:06 +0200 Subject: [PATCH 06/10] fix: code improvements --- .../java/com/thealgorithms/sorts/CountingSort.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/CountingSort.java index a7b2f0af4181..8de0bf780784 100644 --- a/src/main/java/com/thealgorithms/sorts/CountingSort.java +++ b/src/main/java/com/thealgorithms/sorts/CountingSort.java @@ -28,13 +28,12 @@ public > T[] sort(T[] array) { */ @Override public > List sort(List list) { - Map frequencyMap = computeFequencyMap(list); - return extractSortedArray(frequencyMap); + return extractSortedArray(computeFequencyMap(list)); } - private static > List extractSortedArray(Map frequencyMap) { + private static > List extractSortedArray(final Map frequencyMap) { List sortedList = new ArrayList<>(); - for (Map.Entry entry : frequencyMap.entrySet()) { + for (final Map.Entry entry : frequencyMap.entrySet()) { for (int i = 0; i < entry.getValue(); i++) { sortedList.add(entry.getKey()); } @@ -42,10 +41,9 @@ private static > List extractSortedArray(Map> Map computeFequencyMap(List list) { - // TreeMap to maintain order of elements naturally. + private static > Map computeFequencyMap(final List list) { Map frequencyMap = new TreeMap<>(); - for (T element : list) { + for (final T element : list) { frequencyMap.put(element, frequencyMap.getOrDefault(element, 0) + 1); } return frequencyMap; From 82aa523be4e48949db13b1951392d43bb1ee37a3 Mon Sep 17 00:00:00 2001 From: alxklm Date: Sat, 6 Jul 2024 16:51:06 +0200 Subject: [PATCH 07/10] fix: renaming previous counting sort to pseudo counting sort as it is not counting sort --- DIRECTORY.md | 5 ++++- ...ntingSort.java => PseudoCountingSortUsingTreeMap.java} | 2 +- ....java => PseudoCountingSortUsingTreeMapAndStream.java} | 2 +- .../java/com/thealgorithms/sorts/CountingSortTest.java | 8 -------- .../thealgorithms/sorts/CountingSortUsingStreamTest.java | 8 -------- .../PseudoCountingSortUsingTreeMapAndStreamTest.java | 8 ++++++++ .../sorts/PseudoCountingSortUsingTreeMapTest.java | 8 ++++++++ 7 files changed, 22 insertions(+), 19 deletions(-) rename src/main/java/com/thealgorithms/sorts/{CountingSort.java => PseudoCountingSortUsingTreeMap.java} (96%) rename src/main/java/com/thealgorithms/sorts/{CountingSortUsingStream.java => PseudoCountingSortUsingTreeMapAndStream.java} (92%) delete mode 100644 src/test/java/com/thealgorithms/sorts/CountingSortTest.java delete mode 100644 src/test/java/com/thealgorithms/sorts/CountingSortUsingStreamTest.java create mode 100644 src/test/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapAndStreamTest.java create mode 100644 src/test/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapTest.java diff --git a/DIRECTORY.md b/DIRECTORY.md index f6b63d737773..921ddd4f2524 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -513,6 +513,8 @@ * [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) * [PigeonholeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java) + * [PseudoCountingSortUsingTreeMap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMap.java) + * [PseudoCountingSortUsingTreeMapAndStream](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapAndStream.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) * [SelectionSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SelectionSort.java) @@ -866,7 +868,6 @@ * [CocktailShakerSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.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) - * [CountingSortUsingStream](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CountingSortUsingStream.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) @@ -878,6 +879,8 @@ * [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) + * [PseudoCountingSortUsingTreeMapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/sorts/PseudoCountingSortUsingTreeMapTest.java) + * [PseudoCountingSortUsingTreeMapAndStreamTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapAndStreamTest.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) diff --git a/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMap.java similarity index 96% rename from src/main/java/com/thealgorithms/sorts/CountingSort.java rename to src/main/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMap.java index 8de0bf780784..f92f2b71b674 100644 --- a/src/main/java/com/thealgorithms/sorts/CountingSort.java +++ b/src/main/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMap.java @@ -13,7 +13,7 @@ * @author Youssef Ali (https://github.com/youssefAli11997) * @author Podshivalov Nikita (https://github.com/nikitap492) */ -class CountingSort implements SortAlgorithm { +class PseudoCountingSortUsingTreeMap implements SortAlgorithm { @Override public > T[] sort(T[] array) { return sort(Arrays.asList(array)).toArray(array); diff --git a/src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java b/src/main/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapAndStream.java similarity index 92% rename from src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java rename to src/main/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapAndStream.java index 405055793890..ad75c3ba11f1 100644 --- a/src/main/java/com/thealgorithms/sorts/CountingSortUsingStream.java +++ b/src/main/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapAndStream.java @@ -8,7 +8,7 @@ import java.util.TreeMap; import java.util.stream.IntStream; -public class CountingSortUsingStream implements SortAlgorithm { +public class PseudoCountingSortUsingTreeMapAndStream implements SortAlgorithm { @Override public > T[] sort(T[] array) { return streamSort(Arrays.asList(array)).toArray(array); diff --git a/src/test/java/com/thealgorithms/sorts/CountingSortTest.java b/src/test/java/com/thealgorithms/sorts/CountingSortTest.java deleted file mode 100644 index 186ffc9c5ce3..000000000000 --- a/src/test/java/com/thealgorithms/sorts/CountingSortTest.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.thealgorithms.sorts; - -public class CountingSortTest extends SortingAlgorithmTest { - @Override - SortAlgorithm getSortAlgorithm() { - return new CountingSort(); - } -} diff --git a/src/test/java/com/thealgorithms/sorts/CountingSortUsingStreamTest.java b/src/test/java/com/thealgorithms/sorts/CountingSortUsingStreamTest.java deleted file mode 100644 index 39cf216c5987..000000000000 --- a/src/test/java/com/thealgorithms/sorts/CountingSortUsingStreamTest.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.thealgorithms.sorts; - -public class CountingSortUsingStreamTest extends SortingAlgorithmTest { - @Override - SortAlgorithm getSortAlgorithm() { - return new CountingSortUsingStream(); - } -} diff --git a/src/test/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapAndStreamTest.java b/src/test/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapAndStreamTest.java new file mode 100644 index 000000000000..f6112263e2b9 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapAndStreamTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +public class PseudoCountingSortUsingTreeMapAndStreamTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new PseudoCountingSortUsingTreeMapAndStream(); + } +} diff --git a/src/test/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapTest.java b/src/test/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapTest.java new file mode 100644 index 000000000000..04695c21d474 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/PseudoCountingSortUsingTreeMapTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +public class PseudoCountingSortUsingTreeMapTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new PseudoCountingSortUsingTreeMap(); + } +} From 2393b5783d5016e3a10f0944f6ffec32f001658c Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Sat, 6 Jul 2024 16:57:51 +0200 Subject: [PATCH 08/10] fix: changing counting sort to keep it with standard implementation --- .../com/thealgorithms/sorts/CountingSort.java | 54 +++++++++++++++++++ .../thealgorithms/sorts/CountingSortTest.java | 26 +++++++++ 2 files changed, 80 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/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/CountingSort.java new file mode 100644 index 000000000000..038872045861 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/CountingSort.java @@ -0,0 +1,54 @@ +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 does not handle 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; + } + + int max = Arrays.stream(array).max().orElse(Integer.MIN_VALUE); + int min = Arrays.stream(array).min().orElse(Integer.MAX_VALUE); + int range = max - min + 1; + + int[] count = new int[range]; + int[] output = new int[array.length]; + + for (int value : array) { + count[value - min]++; + } + + for (int i = 1; i < count.length; i++) { + count[i] += count[i - 1]; + } + + for (int i = array.length - 1; i >= 0; i--) { + output[count[array[i] - min] - 1] = array[i]; + count[array[i] - min]--; + } + + return output; + } +} 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..75e98c5df629 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/CountingSortTest.java @@ -0,0 +1,26 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import java.util.stream.Stream; + +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})); + } + + @ParameterizedTest + @MethodSource("provideTestCases") + public void testCountingSort(TestCase testCase) { + int[] outputArray = CountingSort.sort(testCase.inputArray); + assertArrayEquals(testCase.expectedArray, outputArray); + } +} From 1855072e08bca1291e9333b13520cb94352552fc Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Sat, 6 Jul 2024 17:00:16 +0200 Subject: [PATCH 09/10] checkstyle: fix formatting --- .../java/com/thealgorithms/sorts/CountingSortTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/thealgorithms/sorts/CountingSortTest.java b/src/test/java/com/thealgorithms/sorts/CountingSortTest.java index 75e98c5df629..d67a0d9be216 100644 --- a/src/test/java/com/thealgorithms/sorts/CountingSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/CountingSortTest.java @@ -12,9 +12,10 @@ 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})); + 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})); } @ParameterizedTest From ada56e0493e61251b44062a3f834c4538ba65498 Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Sat, 6 Jul 2024 17:01:27 +0200 Subject: [PATCH 10/10] checkstyle: fix import ordering --- src/test/java/com/thealgorithms/sorts/CountingSortTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/sorts/CountingSortTest.java b/src/test/java/com/thealgorithms/sorts/CountingSortTest.java index d67a0d9be216..ce6b6aef63c0 100644 --- a/src/test/java/com/thealgorithms/sorts/CountingSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/CountingSortTest.java @@ -2,9 +2,9 @@ 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; -import java.util.stream.Stream; public class CountingSortTest {