记数基数排序

记数基数排序的基础是桶排序,桶排序的一个要求就是要排序的数在一定范围以内,比如最大为K,桶排序的一般步骤有下面三步:
1,建立一个大小为K+2的数组用来记数,(为什么是K+2, 因为我们用k+1的桶来记录k的数量)建立完记数数组之后,就遍历原数组,也就是要排序的数组,遍历一次就使记数加1。
2,对记数数组count[]从新赋值,即第i项的值是前面i-1项的和,这样表示的意思是第i项前面总共有count[i-1] + count[i-2] +...的数小于它,
3,对输出数组赋值,遍历原数组,根据在输出数组的位置来赋值。
下面用一个例子来描述:

 private int[] countSort(int[] oriArray, int k) {
        int[] tagArray = new int[k + 2];
        int sum = 0; //
        int[] sortArray = new int[oriArray.length];
        //step1 记数,用k+1桶表示k桶的数据
       //为什么这么写,后面会说。
        for (int i = 0; i < oriArray.length; i++) {
            tagArray[oriArray[i] + 1]++;
        }
       // step2 对记数数组重新赋值,
        for (int i = 0; i <= k; i++) {
            sum += tagArray[i];
            tagArray[i] = sum;
        }

       // step3 输出数组 
      //通过前面的记数可以发现,tagArray[oriArray[i]]表示的其实是小于oriArray[i]的数量,也就是oriArray[i]在输出数组中的index,后面为什么tagArray[oriArray[i]]++,是因为如果有同样的数,那么就往后加一位。
        for (int i = 0; i < oriArray.length; i++) {
            sortArray[tagArray[oriArray[i]]] = oriArray[i];
            tagArray[oriArray[i]]++;
        }

        for (int i = 0; i < sortArray.length; i++) {
            Log.e("AAA", "the sortarray " + i + " " + sortArray[i]);
        }

        return sortArray;
    }

说完了桶排序,记数基数排序就简单了,看一个简单例子:
假如有一些三位数,要求对他们排序,这个时候用桶排序就不合适了,总不能建1000个桶吧,比如说对下面的数组排序
int[] array = new int[]{367, 236, 544, 123, 532, 894, 353, 934, 477};
当然这些数有点少,但是原理是一样的,先对三位数的个位数进行桶排序,然后对十位数,最后对百位数,代码如下:

 private void countingRadixSort(int[] array, int length) {
        int maxVlue = 10;
        int[] outArray = new int[array.length];
        for (int position = length - 1; position >= 0; position--) {
            int[] count = new int[maxVlue + 1];
            int sum = 0;
            for (int i = 0; i < array.length; i++) {
                count[Integer.parseInt(String.valueOf(String.valueOf(array[i]).charAt(position))) + 1]++;
            }

            for (int b = 0; b < count.length; b++) {
                sum += count[b];
                count[b] = sum;
            }

            for (int i = 0; i < array.length; i++) {
                outArray[count[Integer.parseInt(String.valueOf(String.valueOf(array[i]).charAt(position)))]] = array[i];
                count[Integer.parseInt(String.valueOf(String.valueOf(array[i]).charAt(position)))]++;
            }

            for (int k = 0; k < outArray.length; k++) {
                array[k] = outArray[k];
            }
        }

        for (int i = 0; i < array.length; i++) {
            Log.e("AAA", " array " + i + " is " + array[i]);
        }
    }

中间有一段,Integer.parseInt(String.valueOf(String.valueOf(array[i]).charAt(position)))看着挺吓人,其实就是三位数每个位置上的数值,这段代码的原理就是从低位到高位,用了三次桶排序,当然每次排完的最后要把原数组的值改为输出数组的值,这样可以保存上一次排完的顺序。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 前言 八大排序,三大查找是《数据结构》当中非常基础的知识点,在这里为了复习顺带总结了一下常见的八种排序算法。常见的...
    LeeLom阅读 98,233评论 41 662
  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 14,357评论 0 33
  • 响沙湾。 从小到大跟母亲的第一次单约。也许是为了不留遗憾,也许就是在弥补遗憾。她说:跟我二闺女在一起怎...
    木兮日记阅读 1,198评论 0 0
  • 昨晚漫步湖边 我欲心静如水 争奈 偏偏月儿弯弯如眉 惹得一池春水起漪涟 昨晚漫步湖边 我欲波平如镜 怎奈 偏偏杨柳...
    简非花儿开阅读 1,324评论 0 2
  • 好久之前做过一个梦,梦到自己在世界末日,一个乱世与荒芜的时代,认识了几个人,然后四处游荡,打杀,最后建立了一个...
    林海loo阅读 1,436评论 0 0

友情链接更多精彩内容