18、基数排序

1、简单介绍

1、对电话号码进行排序我们这里也可以借助相同的处理思路,先按照最后一位来排序手机号码,然后,再按照倒数第二位重新排序,以此类推,最后按照第一位重新排序。经过 11 次排序之后,手机号码就都有序了。

2、基数排序:根据每一位来排序,我们可以用刚讲过的桶排序或者计数排序,它们的时间复杂度可以做到O(n)。如果要排序的数据有 k 位,那我们就需要 k 次桶排序或者计数排序,总的时间复杂度是O(k*n)。当 k 不大的时候,比如手机号码排序的例子,k 最大就是 11,所以基数排序的时间复杂度就近似于 O(n)。

3、基数排序是一个稳定的排序。

4、基本思想:我们对一个相同长度,并且是每一位取值范围不大的数,进行计数或者桶排序。

5、基数排序对要排序的数据是有要求的,需要可以分割出独立的“位”来比较,而且位之间有递进的关系,如果 a 数据的高位比 b 数据大,那剩下的低位就不用比较了。除此之外,每一位的数据范围不能太大,要可以用线性排序算法来排序,否则,基数排序的时间复杂度就无法做到 O(n) 了。

2、代码实现


    /**
     * 基数排序
     */
    public void radix_sort(int[] arr) {
        //获取最大值
        int max = getMax(arr);
        int exp = max / 10;

        //对各位  十位  千位 进行排序
        for (int i = 1; i <= exp; i = i * 10) {  //对每一位元素进行计数排序
            count_sort(arr, exp);
        }
    }

    private void count_sort(int[] arr, int exp) {

        //1、因为全部是数字0-9 ,我们按照 10个来计数
        int num = 10;
        int b[] = new int[10];
        //每一个元素出现的次数
        for (int i = 0; i < arr.length; i++) {
            b[arr[i] / exp % 10]++;
        }
        //统计小于等于它的元素个数
        for (int j = 1; j < arr.length; j++) {
            b[j] = b[j - 1] + 1;
        }
        int[] c = new int[arr.length];
        //进行末尾开始比较是为了保证稳定性。
        for (int i = arr.length - 1; i >= 0; i--) {    //  b[arr[i]/exp%10]  表示的是小于等于它的元素出现的次数
            c[b[arr[i] / exp % 10] - 1] = arr[i];
            b[arr[i] / exp % 10]--;
        }
        //进行赋值操作
        for (int j = 0; j < arr.length; j++) {
            arr[j] = c[j];
        }
    }

3、应用

1、我们可以用基数排序来实现电话号码的排序,时间复杂度只需要O(n);

2、可以对英文单词进行排序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值