只适用于非负整数
package Sort
import (
"fmt"
"math"
"testing"
)
/*经典的基数排序:非负数且十进制两个条件
先遍历一遍找最大值,不够用0向前补位
准备十个桶,队列,先进先出
先根据个位数字进桶,从左往右依次,进入对应桶
从左边的桶开始倒数字,倒回原数组就可以
根据十位数字进行依次进桶
倒出
根据百位数字进行依次进桶
倒出
高位数字权重最大,放在最后*/
//基数排序
func RadixSort(arr []int, L, R, digit int) {
const radix = 10 //以10为基数
i, j := 0, 0
help := make([]int, R-L+1) //有多少数就准备多少个空间
for d := 1; d <= digit; d++ { //有多少位就进出多少次
/*
10个空间
count[0] 当前位(d位)是0的数字有多少个
count[1] 当前位(d位)是 0和1 的数字有多少个
count[2] 当前位(d位)是0,1,2的数字有多少个
count[i] 当前位(d位)是0~i的数字有多少个
*/
count := make([]int, radix)
for i = L; i <= R; i++ {
j = getDigit(arr[i], d)
count[j]++
}
for i = 1; i < radix; i++ {
count[i] += count[i-1]
}
for i = R; i >= L; i-- {
j = getDigit(arr[i], d)
help[count[j]-1] = arr[i]
count[j]--
}
for i, j = L, 0; j <= R; i, j = i+1, j+1 {
arr[i] = help[j]
}
}
}
func getDigit(x, d int) int {
//v:= x/int (math.Pow(10, float64(d-1))) % 10
v := (x / QuickPow(10, d-1)) % 10
return v
}
func QuickPow(a, b int) int { //快速求幂 一般
r, base := 1, a
for b != 0 {
if b%2 == 1 {
r *= base
}
base, b = base*base, b/2
}
return r
}
func maxBits(arr []int) int {
max := math.MinInt64
for i := 0; i < len(arr); i++ {
max = Max(max, arr[i])
}
res := 0
for max != 0 {
res++
max /= 10
}
return res
}
func TestRadixSort(t *testing.T) {
arr := []int{122, 2911300, 1111111111, 21111, 3, 0, 32, 31, 9}
RadixSort(arr, 0, len(arr)-1, maxBits(arr)) // 仅限于非负数
fmt.Println(arr)
}
func TestBits(t *testing.T) {
x, d := 12345, 2
v := (x / int(math.Pow(10, float64(d-1)))) % 10
fmt.Println(v)
}