Skip to content

Commit 7b94f75

Browse files
committed
Add Postman Sort (LSD Radix Sort) in R
1 parent b083bc9 commit 7b94f75

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

sorting_algorithms/postman_sort.r

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Postman sort (LSD Radix sort) in R:
2+
3+
# This implements decimal LSD radix sort using a stable counting sort per digit.
4+
# It mirrors the provided Java version: repeatedly apply counting sort by digit
5+
# for exp = 1, 10, 100, ... up to the max number of digits.
6+
7+
postman.sort <- function(elements.vec) {
8+
if (!is.numeric(elements.vec)) stop("postman.sort: elements.vec must be numeric")
9+
n <- length(elements.vec)
10+
if (n <= 1) return(elements.vec)
11+
12+
# Only supports non-negative integers in standard form (typical radix LSD assumption)
13+
if (any(elements.vec < 0)) stop("postman.sort: only non-negative values supported")
14+
15+
# For safety, coerce to integer-like values
16+
if (any(elements.vec != floor(elements.vec))) stop("postman.sort: values must be integers")
17+
18+
get.max <- function(a) max(a)
19+
20+
counting.sort.by.digit <- function(a, exp) {
21+
n <- length(a)
22+
output <- numeric(n)
23+
count <- integer(10) # digits 0..9
24+
25+
# Count occurrences
26+
for (i in seq_len(n)) {
27+
digit <- (a[i] %/% exp) %% 10
28+
count[digit + 1L] <- count[digit + 1L] + 1L
29+
}
30+
31+
# Prefix sums for positions (1-based indexing in R)
32+
for (i in 2:10) {
33+
count[i] <- count[i] + count[i - 1L]
34+
}
35+
36+
# Build output stable, iterate from end
37+
for (i in n:1) {
38+
digit <- (a[i] %/% exp) %% 10
39+
idx <- count[digit + 1L]
40+
output[idx] <- a[i]
41+
count[digit + 1L] <- idx - 1L
42+
}
43+
44+
return(output)
45+
}
46+
47+
max.val <- get.max(elements.vec)
48+
exp <- 1
49+
while ((max.val %/% exp) > 0) {
50+
elements.vec <- counting.sort.by.digit(elements.vec, exp)
51+
exp <- exp * 10
52+
}
53+
54+
return(elements.vec)
55+
}
56+
57+
# Example:
58+
# postman.sort(c(170, 45, 75, 90, 802, 24, 2, 66))
59+
# [1] 2 24 45 66 75 90 170 802

0 commit comments

Comments
 (0)