Java-桶排序(计数排序&基数排序)

本是古典 何须时尚 2023-10-08 21:55 93阅读 0赞

桶排序是非基于比较排序的

计数排序(非负十进制):先准备十个队列 然后按个位数字进桶

桶排序是一种思想:一个坑好几个萝卜

计数排序的思想很简单:员工的年龄(18-35),那就创建(35-18+1)个桶,然后遍历员工年龄的数组放在对应的桶中然后再输出就可以了.

  1. public static void radixSort(int [] arr) {
  2. if(arr==null||arr.length<2) {
  3. return;
  4. }
  5. radixSort(arr,0,arr.length-1,maxbits(arr));
  6. }
  7. public static int maxbits(int [] arr) {
  8. int max = Integer.MIN_VALUE;
  9. for(int i = 0;i<arr.length;i++) {
  10. max = Math.max(max,arr[i]);
  11. }
  12. int count = 0;
  13. while(max!=0) {
  14. max/=10;
  15. count++;
  16. }
  17. return count;
  18. }
  19. public static int getbits(int num,int bitnum) {
  20. for(int i = 1;i<=bitnum-1;i++) {
  21. num = num/10;
  22. }
  23. return num%10;
  24. }
  25. public static void radixSort(int [] arr,int L,int R,int digit) {
  26. int radix = 10;
  27. int [] help = new int [R-L+1];
  28. int i = 0;
  29. int j = 0;
  30. for(int d = 1;d<=digit;d++) {
  31. int [] count = new int [radix];
  32. for(i = L; i <= R; i++) {
  33. j = getbits(arr[i], d);
  34. count[j]++;
  35. }
  36. for(i = 1;i<radix;i++) {
  37. count[i] += count[i-1];
  38. }
  39. for(i = R;i>=L;i--) {
  40. j = getbits(arr[i], d);
  41. help[count[j]-1] = arr[i];
  42. count[j]--;
  43. }
  44. for (i = L, j = 0; i <= R; i++, j++) {
  45. arr[i] = help[j];
  46. }
  47. }
  48. }
  49. public static void main(String[] args) {
  50. int [] arr = {1,3,5,7,9,2,4,6,8,10};
  51. radixSort(arr);
  52. System.out.println(Arrays.toString(arr));
  53. }

基数排序的原理并不复杂 有一批数,先按个位数字大小排序,然后十位…….

举个例子 {11,1,18,4,27,635,621,55,9}这坨数

首先按第一位排: 11,1,621,4,635,55,27,18,9

然后在此基础上 用第二位排: 1,4,9,11,18,621,27,635,55

在此基础上 用第三位排:1,4,9,11,18,27,55,621,635

这个原理是怎么回事呢 先用小位数上的排序 但是高位数上的数字对这个数的大小影响更大 所以再在此基础上对其排序

代码实现为了减少空间的消耗所以看起来很复杂….

男♂以理解的部分其实 只有41行到48行的部分 一个是累加 一个是倒序放置 在代码注释里面已经给出了(同样很难理解的)解释

  1. public static void radixSort(int[] arr) {
  2. if (arr == null || arr.length < 2) {
  3. return;
  4. }
  5. radixSort(arr, 0, arr.length - 1, maxbits(arr));
  6. }
  7. public static int maxbits(int[] arr) {
  8. int max = Integer.MIN_VALUE;
  9. for (int i = 0; i < arr.length; i++) {
  10. max = Math.max(max, arr[i]);
  11. }
  12. int res = 0;
  13. while (max != 0) {
  14. res++;
  15. max /= 10;
  16. }
  17. return res;
  18. }
  19. // arr[l..r]排序 , digit
  20. // l..r 3 56 17 100 3
  21. public static void radixSort(int[] arr, int L, int R, int digit) {
  22. final int radix = 10;
  23. int i = 0, j = 0;
  24. // 有多少个数准备多少个辅助空间
  25. int[] help = new int[R - L + 1];
  26. for (int d = 1; d <= digit; d++) { // 有多少位就进出几次
  27. // 10个空间
  28. // count[0] 当前位(d位)是0的数字有多少个
  29. // count[1] 当前位(d位)是(0和1)的数字有多少个
  30. // count[2] 当前位(d位)是(0、1和2)的数字有多少个
  31. // count[i] 当前位(d位)是(0~i)的数字有多少个
  32. int[] count = new int[radix]; // count[0..9]
  33. for (i = L; i <= R; i++) {
  34. // 103 1 3
  35. // 209 1 9
  36. j = getDigit(arr[i], d);
  37. count[j]++;
  38. }//计算d位是j的数有多少个 计数排序啊
  39. for (i = 1; i < radix; i++) {
  40. count[i] = count[i] + count[i - 1];//累加上去 当前位是i~0的有多少个
  41. }//意义就是下面的arr[i]它该放在第几个
  42. for (i = R; i >= L; i--) {//倒序放置 是在上一次(前一位)排序基础上再进行排序 算是计数排序的核心
  43. j = getDigit(arr[i], d);
  44. help[count[j] - 1] = arr[i];//
  45. count[j]--;
  46. }
  47. for (i = L, j = 0; i <= R; i++, j++) {
  48. arr[i] = help[j];//把help中的值赋给arr
  49. }
  50. }
  51. }
  52. public static int getDigit(int x, int d) {
  53. return ((x / ((int) Math.pow(10, d - 1))) % 10);
  54. }

发表评论

表情:
评论列表 (有 0 条评论,93人围观)

还没有评论,来说两句吧...

相关阅读

    相关 排序之后 --- > 基数排序

    和桶排序一样,也不是基于比较的。 基数排序一般用于整数的处理,它的基本原理是:一直想把它说的更白话一点,可是,哎。。。 我们可以想象一下,如果现在只有几个各位数   2