桶排序——基数排序

Posted 不做油腻的中年大叔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了桶排序——基数排序相关的知识,希望对你有一定的参考价值。

一、回顾

  • 桶排序是一种基于数据状况的排序,不基于比较

  • 计数排序是基于这些数的范围大小的排序

基数排序是基于这些数的位数的排序

二、思路

  1. 获取待排序数组的最大数max

  2. 拿到此最大数的位数,就代表了这些数的最大位数

  3. 按照位数(个、十、百、千......)来进行所有数的排序

    • 准备10个桶,分别是0~9位,桶中记的是个数

    • 遍历所有的数,统计此位数有几个

    • 将桶中的个数做处理,就知道了在原数组中的位置范围(见代码)

    • 再次遍历数组,根据桶中的信息,来将原数组按位数有序的方式进行排序

三、代码

思路理解起来比较复杂,看看代码

public static void radixSort(int[] arr){
   if(arr == null || arr.length < 2){
       return ;
  }
   // maxbits找出这些数的最高位数
   radixSort(arr, 0, arr.length - 1, maxbits(arr));
}

public static void radixSort(int[] arr, int begin, int end, int digit){
   final int radix = 10;
   int[] count = new int[radix]; // 10个桶,0~9位
   int[] help = new int[end-begin+1];
   int i = 0, j = 0;
   for(int d = 1; d <= digit; d++){
       for(i = 0; i < count.length; i++){
           count[i] = 0; // 清空桶中的数据,方便下一轮迭代
      }
       for(i = begin; i <= end; i++){
           j = getDigit(arr[i], d); // 找到arr[i]第d位对应的数
           count[j]++;
      }
       // 处理统计,count[i]记录了这个位数是多少的数,在原数组中的位置范围
       for(i = 1; i < count.length; i++){
           count[i] = count[i] + count[i - 1];
      }
       /**
        * 如果i每次从开头而不是结尾开始
        * 而count每次都是从这个位数范围的最大数的位置开始赋值
        * 所以如果次序已经按照之前位数排好,经过这一步应该正好在前一位上的结果倒序了
        * 比如按照第一位排好后:10, 3, 3, 7, 8
        * 如果i每次从头开始,经过第二位排好后:8, 7, 3, 3, 10
        */
       for(i = end; i >= begin; i--){
           j = getDigit(arr[i], d);
           help[--count[j]] = arr[i];
      }
       //help数组任务结束
       for(i = 0; i < help.length; i++){
           arr[begin+i] = help[i];
      }
  }
}

public static int getDigit(int x, int d){
   return ((x / ((int)(Math.pow(10, d - 1)))) % 10 );
}

public static int maxbits(int[] arr){
   int max = Integer.MIN_VALUE;
   int res = 0;
   for(int i = 0; i < arr.length; i++){
       max = Math.max(max, arr[i]);
  }
   while(max != 0){
       res++;
       max /= 10;
  }
   return res;
}

四、复杂度

实现上可以做到稳定,时间复杂度O(n),空间复杂度O(n)


以上是关于桶排序——基数排序的主要内容,如果未能解决你的问题,请参考以下文章

基数排序 vs 计数排序 vs 桶排序。有啥不同?

---------快排-----表排-----基数排序(桶排序)-----

桶排序——基数排序

桶排序之基数排序

八十五再探希尔排序,桶排序,计数排序和基数排序

桶排序和基数排序有啥区别?