-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathlsd.go
105 lines (86 loc) · 2.28 KB
/
lsd.go
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package sort
import "github.com/youngzhu/algs4-go/strings"
// Least-Significant-Digit First (LSD) radix sort for fixed length strings.
// It includes a method for sorting 32-bit integers, treating each integer as
// a 4-byte string. When N is large, this algorithm is 2-3x faster than the system sort.
// - Sort a string[] array of n extended ASCII strings (R=256), each of length w
// - Sort an int[] array of n 32-bit integers, treating each integer as a sequence
// of w=4 bytes
// Uses extra space proportional to n+R
// Rearranges the array of w-character strings in ascending order.
func LSDSort(a []string) {
// check that strings have fixed length
w := len(a[0])
for _, s := range a {
if len(s) != w {
panic("strings must have fixed length")
}
}
n := len(a)
aux := make([]string, n)
// sort by key-indexed counting on dth character
for d := w - 1; d >= 0; d-- {
//compute frequency counts
count := make([]int, strings.R+1)
for i := 0; i < n; i++ {
count[a[i][d]+1]++
}
// compute cumulates
for r := 0; r < strings.R; r++ {
count[r+1] += count[r]
}
// move data
for i := 0; i < n; i++ {
aux[count[a[i][d]]] = a[i]
count[a[i][d]]++
}
// copy back
for i := 0; i < n; i++ {
a[i] = aux[i]
}
}
}
/* Didn't work. Don't know why */
// Rearranges the array of 32-bit integers in ascending order
func LSDSortInts(a []int) {
bits := 32 // each int is 32 bits
bitsPerByte := 8
R := 1 << bitsPerByte // each bytes is between 0 and 255
mask := R - 1 // 0xFF
w := bits / bitsPerByte // each int is 4 byte
n := len(a)
aux := make([]int, n)
for d := 0; d < w; d++ {
// compute frequency counts
count := make([]int, R+1)
for i := 0; i < n; i++ {
c := (a[i] >> bitsPerByte * d) & mask
count[c+1]++
}
// compute cumulates
for r := 0; r < R; r++ {
count[r+1] += count[r]
}
// for most significant byte, 0x80-0xFF come before 0x00-0x7F
if d == w-1 {
shift1 := count[R] - count[R/2]
shift2 := count[R/2]
for r := 0; r < R/2; r++ {
count[r] += shift1
}
for r := R / 2; r < R; r++ {
count[r] -= shift2
}
}
// move data
for i := 0; i < n; i++ {
c := (a[i] >> bitsPerByte * d) & mask
aux[count[c]] = a[i]
count[c]++
}
// copy back
for i := 0; i < n; i++ {
a[i] = aux[i]
}
}
}