-
Notifications
You must be signed in to change notification settings - Fork 1
/
radix.ts
70 lines (59 loc) · 2.15 KB
/
radix.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
* Radix Sort is a non-comparative sorting algorithm. Its time complexity
* depends on the number of digits (or the length of the strings or keys)
* used to represent the numbers. Let's denote:
* - n: the number of elements in the array
* - k: the maximum number of digits (or the length of the longest key)
*
* Time Complexity: O (n x k)
* 1. In the case where k is not significantly larger than n (or is less than n),
* Radix Sort can linearly sort numbers or strings, which can be faster than
* comparison-based sorting algorithms.
*
* 2. However, if k is very large, the efficiency of Radix Sort can degrade,
* making it less suitable for certain scenarios.
*
* Space Complexity: O (n x k)
*
* Remember, the exact efficiency and suitability of Radix Sort will
* depend on the specific nature and distribution of the data being sorted.
*
* @param arr passed array of numbers to srt
* @returns sorted array of numbers
*/
export function radixSort(arr: number[]): number[] {
if (arr.length <= 1) return arr
const maxNum = Math.max(...arr.map((num) => Math.abs(num)))
const maxLen = Math.floor(Math.log10(maxNum) + 1)
let negatives = arr.filter((num) => num < 0)
let positives = arr.filter((num) => num >= 0)
for (let position = 0; position < maxLen; position++) {
positives = countingSortForRadix(positives, position)
negatives = countingSortForRadix(negatives, position)
}
return [...negatives.reverse(), ...positives]
}
function countingSortForRadix(arr: number[], position: number): number[] {
const count: number[] = Array<number>(10).fill(0)
arr.forEach((num) => {
const digit = getDigit(num, position)
count[digit]++
})
for (let i = 1; i < count.length; i++) {
count[i] += count[i - 1]
}
const output = new Array<number>(arr.length)
arr
.slice()
.reverse()
.forEach((num) => {
const digit = getDigit(num, position)
output[--count[digit]] = num
})
return output
}
function getDigit(num: number, position: number): number {
const str = Math.abs(num).toString()
return str.length > position ? +str[str.length - 1 - position] : 0
}
export type RadixSortFn = typeof radixSort