基数排序

基数排序(Radix sort) 是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

算法原理

基数排序的算法原理:

  • 将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

  • 基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。

LSD 基数排序动图演示:

基数排序 - 图1

基数排序算法实现:

  1. func main() {
  2. array := []int{12, 3, 8, 5, 9, 11, 23, 36,20,28,21}
  3. fmt.Println("before radixSort:",array)
  4. radixSort(array)
  5. fmt.Println("after radixSort:",array)
  6. }
  7. //获取数组的最大值
  8. func maxValue(arr []int) (ret int) {
  9. ret = 1
  10. var key int = 10
  11. for i := 0; i < len(arr); i++ {
  12. for arr[i] >= key {
  13. key = key * 10
  14. ret++
  15. }
  16. }
  17. return
  18. }
  19. func radixSort(arr []int) {
  20. key := maxValue(arr)
  21. tmp := make([]int, len(arr), len(arr))
  22. count := new([10]int)
  23. radix := 1
  24. var i, j, k int
  25. for i = 0; i < key; i++ { //进行key次排序
  26. for j = 0; j < 10; j++ {
  27. count[j] = 0
  28. }
  29. for j = 0; j < len(arr); j++ {
  30. k = (arr[j] / radix) % 10
  31. count[k]++
  32. }
  33. for j = 1; j < 10; j++ { //将tmp中的为准依次分配给每个桶
  34. count[j] = count[j-1] + count[j]
  35. }
  36. for j = len(arr) - 1; j >= 0; j-- {
  37. k = (arr[j] / radix) % 10
  38. tmp[count[k]-1] = arr[j]
  39. count[k]--
  40. }
  41. for j = 0; j <len(arr); j++ {
  42. arr[j] = tmp[j]
  43. }
  44. radix = radix * 10
  45. }
  46. }

运行结果:

  1. before radixSort: [12 3 8 5 9 11 23 36 20 28 21]
  2. after radixSort: [3 5 8 9 11 12 20 21 23 28 36]