数据结构---基数排序


时间复杂度为线性的排序算法:

  1. 计数排序
  2. 桶排序
  3. 基数排序

算法思想

把排序工作拆分成多个阶段,每一个阶段只根据一个字符进行计数排序,一共排序k轮(k是字符串的长度)。

使用的计数排序必须是稳定排序,这样才能保证第1轮排出的先后顺序在第2轮还能继续保持。

从高位优先进行排序(Most Significant Digitfirst,简称MSD)
从低位优先进行排序(Least SignificantDigit first,简称LSD)

对齐问题

以最长的字符串为准,其他长度不足的字符串,在末尾补0即可。
在排序时,我们把字符0当作比a更小的字符

JAVA实现

    //ascii码的取值范围
    public static final int ASCII_RANGE = 128;

    public static String[] radixSort(String[] array, int maxLength) {
        //排序结果数组,用于存储每一次按位排序的临时结果
        String[] sortedArray = new String[array.length];
        //从个位开始比较,一直比较到最高位
        for (int k = maxLength - 1; k >= 0; k--) {
            //计数排序的过程,分成三步:
            //1.创建辅助排序的统计数组,并把待排序的字符对号入座,
            //这里为了代码简洁,直接使用ascii码范围作为数组长度
            //count数组相当于计数排序里面的统计数组(下标代表字母对应的ascll码)
            int[] count = new int[ASCII_RANGE];
            for (int i = 0; i < array.length; i++) {
                int index = getCharIndex(array[i], k);
                count[index]++;
            }
            //2.统计数组做变形,后面的元素等于前面的元素之和
            // (这个是优化计数排序的过程,如果遇到相同的原始,就按照原始的位置输出)
            for (int i = 1; i < count.length; i++) {
                count[i] = count[i] + count[i - 1];
            }
            //3.倒序遍历原始数列,从统计数组找到正确位置,输出到结果数组
            for (int i = array.length - 1; i >= 0; i--) {
                int index = getCharIndex(array[i], k);
                int sortedIndex = count[index] - 1;
                sortedArray[sortedIndex] = array[i];
                count[index]--;
            }
            //下一轮排序需要以上一轮的排序结果为基础,因此把结果复制给array
            array = sortedArray.clone();
        }
        return array;
    }

    //获取字符串第k位字符所对应的ascii码序号
    private static int getCharIndex(String str, int k) {
        //如果字符串长度小于k,直接返回0,相当于给不存在的位置补0
        if (str.length() < (k + 1)) {
            return 0;
        }
        return str.charAt(k);
    }

测试方法:

    public static void main(String[] args) {
        String[] array = { "qd", "abc", "qwe", "hhh", "a", "cws", "ope" };
        System.out.println(Arrays.toString(radixSort(array, 3)));
    }

在这里插入图片描述

时间复杂度:O(k(n+m))
k是字符串最大长度,m是字符范围。
空间复杂度:O(n+m)

总结

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值