|
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