|
1 | 1 | package algorithms.sorting.radixSort; |
2 | 2 |
|
3 | 3 | /** |
4 | | - * Implementation of Radix sort. |
5 | | - * O((b/r)*(N + 2^r)) |
6 | | - * where N is the number of integers, |
7 | | - * b is the total number of bits (32 bits for int), |
8 | | - * and r is the number of bits for each segment. |
9 | | - * Space: O(N) auxiliary space. |
10 | | - */ |
| 4 | +* This class implements a Radix Sort Algorithm. |
| 5 | +*/ |
11 | 6 | public class RadixSort { |
12 | | - private static final int NUM_BITS = 8; |
13 | | - private static final int NUM_SEGMENTS = 4; |
14 | 7 |
|
15 | | - private static int getSegmentMasked(int num, int segment) { |
16 | | - int mask = ((1 << NUM_BITS) - 1) << (segment * NUM_BITS); |
17 | | - return (num & mask) >> (segment * NUM_BITS); |
18 | | - } |
| 8 | + private static final int NUM_BITS = 8; |
| 9 | + private static final int NUM_SEGMENTS = 4; |
19 | 10 |
|
20 | | - private static void radixSort(int[] arr, int[] sorted) { |
21 | | - // sort the N numbers by segments, starting from left-most segment |
22 | | - for (int i = 0; i < NUM_SEGMENTS; i++) { |
23 | | - int[] freqMap = new int[1 << NUM_BITS]; // at most this number of elements |
| 11 | + /** |
| 12 | + * Creates masking on the segment to obtain the value of the digit. |
| 13 | + * |
| 14 | + * @param num The number. |
| 15 | + * @param segment The segment we are interested in. |
| 16 | + * |
| 17 | + * @return The value of the digit in the number at the given segment. |
| 18 | + */ |
| 19 | + private static int getSegmentMasked(int num, int segment) { |
| 20 | + // Bit masking here to extract each segment from the integer. |
| 21 | + int mask = ((1 << NUM_BITS) - 1) << (segment * NUM_BITS); |
| 22 | + return (num & mask) >> (segment * NUM_BITS); |
| 23 | + } |
24 | 24 |
|
25 | | - // count each element |
26 | | - for (int num : arr) { |
27 | | - freqMap[getSegmentMasked(num, i)]++; |
28 | | - } |
29 | | - // get prefix sum |
30 | | - for (int j = 1; j < freqMap.length; j++) { |
31 | | - freqMap[j] += freqMap[j-1]; |
32 | | - } |
33 | | - // place each number in its correct sorted position up until the given segment |
34 | | - for (int k = arr.length-1; k >= 0; k--) { |
35 | | - int curr = arr[k]; |
36 | | - int id = getSegmentMasked(curr, i); |
37 | | - sorted[freqMap[id] - 1] = curr; |
38 | | - freqMap[id]--; |
39 | | - } |
40 | | - // we do a swap so that our results above for this segment is saved and passed as input to the next segment |
41 | | - int[] tmp = arr; |
42 | | - arr = sorted; |
43 | | - sorted = tmp; |
44 | | - } |
45 | | - sorted = arr; |
46 | | - } |
| 25 | + /** |
| 26 | + * Radix sorts a given input array and updates the output array in-place. |
| 27 | + * |
| 28 | + * @param arr original input array. |
| 29 | + * @param sorted output array. |
| 30 | + */ |
| 31 | + private static void radixSort(int[] arr, int[] sorted) { |
| 32 | + // sort the N numbers by segments, starting from left-most segment |
| 33 | + for (int i = 0; i < NUM_SEGMENTS; i++) { |
| 34 | + int[] freqMap = new int[1 << NUM_BITS]; // at most this number of elements |
47 | 35 |
|
48 | | - public static void radixSort(int[] arr) { |
49 | | - int[] sorted = new int[arr.length]; |
50 | | - radixSort(arr, sorted); |
51 | | - arr = sorted; // swap back lol |
| 36 | + // count each element |
| 37 | + for (int num : arr) { |
| 38 | + freqMap[getSegmentMasked(num, i)]++; |
| 39 | + } |
| 40 | + // get prefix sum |
| 41 | + for (int j = 1; j < freqMap.length; j++) { |
| 42 | + freqMap[j] += freqMap[j - 1]; |
| 43 | + } |
| 44 | + // place each number in its correct sorted position up until the given segment |
| 45 | + for (int k = arr.length - 1; k >= 0; k--) { |
| 46 | + int curr = arr[k]; |
| 47 | + int id = getSegmentMasked(curr, i); |
| 48 | + sorted[freqMap[id] - 1] = curr; |
| 49 | + freqMap[id]--; |
| 50 | + } |
| 51 | + // We do a swap so that our results above for this segment is |
| 52 | + // saved and passed as input to the next segment. |
| 53 | + // By doing this we no longer need to create a new array |
| 54 | + // every time we shift to a new segment to sort. |
| 55 | + // We can constantly reuse the array, allowing us to only use O(n) space. |
| 56 | + int[] tmp = arr; |
| 57 | + arr = sorted; |
| 58 | + sorted = tmp; |
52 | 59 | } |
| 60 | + sorted = arr; |
| 61 | + } |
| 62 | + |
| 63 | + /** |
| 64 | + * Calls radix sort inplace on a given array. |
| 65 | + * |
| 66 | + * @param arr The array to be sorted. |
| 67 | + */ |
| 68 | + public static void radixSort(int[] arr) { |
| 69 | + int[] sorted = new int[arr.length]; |
| 70 | + radixSort(arr, sorted); |
| 71 | + arr = sorted; // swap back lol |
| 72 | + } |
53 | 73 | } |
0 commit comments