|
| 1 | +/** |
| 2 | + * Radix Sort is a non-comparison integer sorting algorithm that sorts integers |
| 3 | + * by processing individual digits. It sorts by grouping keys by the individual |
| 4 | + * digits which share the same significant position and value. |
| 5 | + * |
| 6 | + * Time Complexity: O(d * (n + b)) where d is the number of digits in the |
| 7 | + * largest number, n is the size of the input, and b is the base (10 for decimal). |
| 8 | + * |
| 9 | + * For more info: https://en.wikipedia.org/wiki/Radix_sort |
| 10 | + */ |
| 11 | + |
| 12 | +// A helper function for Radix Sort that uses Counting Sort to sort the elements |
| 13 | +// based on a significant digit. |
| 14 | +function countingSortForRadix(array: number[], digit: number): number[] { |
| 15 | + const n = array.length; |
| 16 | + const output: number[] = new Array(n).fill(0); |
| 17 | + const count: number[] = new Array(10).fill(0); |
| 18 | + |
| 19 | + // Store count of occurrences in count[] |
| 20 | + for (let i = 0; i < n; i++) { |
| 21 | + const index = Math.floor(array[i] / digit) % 10; |
| 22 | + count[index]++; |
| 23 | + } |
| 24 | + |
| 25 | + // Change count[i] so that count[i] now contains the actual |
| 26 | + // position of this digit in output[] |
| 27 | + for (let i = 1; i < 10; i++) { |
| 28 | + count[i] += count[i - 1]; |
| 29 | + } |
| 30 | + |
| 31 | + // Build the output array. We iterate from the end to make it a stable sort. |
| 32 | + for (let i = n - 1; i >= 0; i--) { |
| 33 | + const index = Math.floor(array[i] / digit) % 10; |
| 34 | + output[count[index] - 1] = array[i]; |
| 35 | + count[index]--; |
| 36 | + } |
| 37 | + |
| 38 | + return output; |
| 39 | +} |
| 40 | + |
| 41 | +export function radixSort(array: number[]): number[] { |
| 42 | + if (array.length === 0) { |
| 43 | + return []; |
| 44 | + } |
| 45 | + |
| 46 | + // Create a copy to avoid modifying the original array (pure function) |
| 47 | + let result = [...array]; |
| 48 | + |
| 49 | + // Find the maximum number to know the number of digits |
| 50 | + const maxNumber = Math.max(...result); |
| 51 | + |
| 52 | + // Do counting sort for every digit. Note that instead of passing digit |
| 53 | + // number, digit is passed. digit is 10^i where i is current digit number. |
| 54 | + for (let digit = 1; Math.floor(maxNumber / digit) > 0; digit *= 10) { |
| 55 | + result = countingSortForRadix(result, digit); |
| 56 | + } |
| 57 | + |
| 58 | + return result; |
| 59 | +} |
| 60 | + |
| 61 | +// --- Example Usage --- |
| 62 | +if (require.main === module) { |
| 63 | + const unsortedArray = [170, 45, 75, 90, 802, 24, 2, 66]; |
| 64 | + console.log('Original Array:', unsortedArray); |
| 65 | + const sortedArray = radixSort(unsortedArray); |
| 66 | + console.log('Sorted Array:', sortedArray); // Output: [ 2, 24, 45, 66, 75, 90, 170, 802 ] |
| 67 | +} |
0 commit comments