|
1 | 1 | package com.thealgorithms.sorts;
|
2 | 2 |
|
| 3 | +import com.thealgorithms.maths.NumberOfDigits; |
3 | 4 | import java.util.Arrays;
|
4 | 5 |
|
5 |
| -final class RadixSort { |
| 6 | +/** |
| 7 | + * This class provides an implementation of the radix sort algorithm. |
| 8 | + * It sorts an array of nonnegative integers in increasing order. |
| 9 | + */ |
| 10 | +public final class RadixSort { |
| 11 | + private static final int BASE = 10; |
| 12 | + |
6 | 13 | private RadixSort() {
|
7 | 14 | }
|
8 | 15 |
|
9 |
| - private static int getMax(int[] arr, int n) { |
10 |
| - int mx = arr[0]; |
11 |
| - for (int i = 1; i < n; i++) { |
12 |
| - if (arr[i] > mx) { |
13 |
| - mx = arr[i]; |
14 |
| - } |
| 16 | + /** |
| 17 | + * Sorts an array of nonnegative integers using the radix sort algorithm. |
| 18 | + * |
| 19 | + * @param array the array to be sorted |
| 20 | + * @return the sorted array |
| 21 | + * @throws IllegalArgumentException if any negative integers are found |
| 22 | + */ |
| 23 | + public static int[] sort(int[] array) { |
| 24 | + if (array.length == 0) { |
| 25 | + return array; |
15 | 26 | }
|
16 |
| - return mx; |
17 |
| - } |
18 | 27 |
|
19 |
| - private static void countSort(int[] arr, int n, int exp) { |
20 |
| - int[] output = new int[n]; |
21 |
| - int i; |
22 |
| - int[] count = new int[10]; |
23 |
| - Arrays.fill(count, 0); |
| 28 | + checkForNegativeInput(array); |
| 29 | + radixSort(array); |
| 30 | + return array; |
| 31 | + } |
24 | 32 |
|
25 |
| - for (i = 0; i < n; i++) { |
26 |
| - count[(arr[i] / exp) % 10]++; |
| 33 | + /** |
| 34 | + * Checks if the array contains any negative integers. |
| 35 | + * |
| 36 | + * @param array the array to be checked |
| 37 | + * @throws IllegalArgumentException if any negative integers are found |
| 38 | + */ |
| 39 | + private static void checkForNegativeInput(int[] array) { |
| 40 | + for (int number : array) { |
| 41 | + if (number < 0) { |
| 42 | + throw new IllegalArgumentException("Array contains non-positive integers."); |
| 43 | + } |
27 | 44 | }
|
| 45 | + } |
28 | 46 |
|
29 |
| - for (i = 1; i < 10; i++) { |
30 |
| - count[i] += count[i - 1]; |
| 47 | + private static void radixSort(int[] array) { |
| 48 | + final int max = Arrays.stream(array).max().getAsInt(); |
| 49 | + for (int i = 0, exp = 1; i < NumberOfDigits.numberOfDigits(max); i++, exp *= BASE) { |
| 50 | + countingSortByDigit(array, exp); |
31 | 51 | }
|
| 52 | + } |
32 | 53 |
|
33 |
| - for (i = n - 1; i >= 0; i--) { |
34 |
| - output[count[(arr[i] / exp) % 10] - 1] = arr[i]; |
35 |
| - count[(arr[i] / exp) % 10]--; |
36 |
| - } |
| 54 | + /** |
| 55 | + * A utility method to perform counting sort of array[] according to the digit represented by exp. |
| 56 | + * |
| 57 | + * @param array the array to be sorted |
| 58 | + * @param exp the exponent representing the current digit position |
| 59 | + */ |
| 60 | + private static void countingSortByDigit(int[] array, int exp) { |
| 61 | + int[] count = countDigits(array, exp); |
| 62 | + accumulateCounts(count); |
| 63 | + int[] output = buildOutput(array, exp, count); |
| 64 | + copyOutput(array, output); |
| 65 | + } |
37 | 66 |
|
38 |
| - System.arraycopy(output, 0, arr, 0, n); |
| 67 | + private static int[] countDigits(int[] array, int exp) { |
| 68 | + int[] count = new int[BASE]; |
| 69 | + for (int i = 0; i < array.length; i++) { |
| 70 | + count[getDigit(array[i], exp)]++; |
| 71 | + } |
| 72 | + return count; |
39 | 73 | }
|
40 | 74 |
|
41 |
| - private static void radixsort(int[] arr, int n) { |
42 |
| - int m = getMax(arr, n); |
| 75 | + private static int getDigit(int number, int position) { |
| 76 | + return (number / position) % BASE; |
| 77 | + } |
43 | 78 |
|
44 |
| - for (int exp = 1; m / exp > 0; exp *= 10) { |
45 |
| - countSort(arr, n, exp); |
| 79 | + private static void accumulateCounts(int[] count) { |
| 80 | + for (int i = 1; i < BASE; i++) { |
| 81 | + count[i] += count[i - 1]; |
46 | 82 | }
|
47 | 83 | }
|
48 | 84 |
|
49 |
| - static void print(int[] arr, int n) { |
50 |
| - for (int i = 0; i < n; i++) { |
51 |
| - System.out.print(arr[i] + " "); |
| 85 | + private static int[] buildOutput(int[] array, int exp, int[] count) { |
| 86 | + int[] output = new int[array.length]; |
| 87 | + for (int i = array.length - 1; i >= 0; i--) { |
| 88 | + int digit = getDigit(array[i], exp); |
| 89 | + output[count[digit] - 1] = array[i]; |
| 90 | + count[digit]--; |
52 | 91 | }
|
| 92 | + return output; |
53 | 93 | }
|
54 | 94 |
|
55 |
| - public static void main(String[] args) { |
56 |
| - int[] arr = {170, 45, 75, 90, 802, 24, 2, 66}; |
57 |
| - int n = arr.length; |
58 |
| - radixsort(arr, n); |
59 |
| - print(arr, n); |
| 95 | + private static void copyOutput(int[] array, int[] output) { |
| 96 | + System.arraycopy(output, 0, array, 0, array.length); |
60 | 97 | }
|
61 | 98 | }
|
62 |
| -// Written by James Mc Dermott(theycallmemac) |
|
0 commit comments