动画:一篇文章快速学会基数排序

内容介绍

基数排序简介

前面学过计数排序桶排序都是非基于比较的排序算法,它们的优点在于对必定范围内的数据排序时能够突破基于比较排序算法的时间复杂度O(nlogn)。java

基数排序是一种非比较型整数排序算法,基数排序的发明能够追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献。git

基数排序的思想

基数排序(Radix Sort)是计数排序的扩展,它的基本思想是:将整数按位数分割成不一样的数字,而后按每一个位数分别比较。 具体作法是:将全部待排序数值(正整数)统一为一样的数位长度,数位较短的数前面补零。而后从最低位开始,依次进行排序。这样从最低位排序一直到最高位排序完成之后, 数列就变成一个有序数列。算法

基数排序动画演示

假设有{16, 28, 19, 65, 95, 98, 81, 77, 18, 15}这10个数据。通常没有特殊要求排序算法都是升序排序,小的在前,大的在后,效果以下: 编程

基数序分析

经过上面动画能够看出基数排序就是将数字按位分割,每一位进行一次计数排序,最终完成排序。数组

首先使用个位进行一次计数排序,效果以下: 微信

接着使用十位进行计数排序,效果以下: 动画

最终排序效果以下: code

基数排序代码编写

public class RadixSort {
    public static void main(String[] args) {
        int[] arr = {16, 28, 19, 65, 95, 98, 81, 77, 18, 15};

        radixSort(arr);
        System.out.println("排序后: " + Arrays.toString(arr));
    }

    public static void radixSort(int[] arr) {
        // 获取数组中最大元素
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max)
                max = arr[i];
        }

        // 按位进行计数排序
        for (int exp = 1; max/exp > 0; exp *= 10) {
            countingSort(arr, exp);
            System.out.println("radixSort = " + Arrays.toString(arr));
        }
    }

    private static void countingSort(int[] arr, int exp) {
        // 1.定义统计数组
        int[] countArr = new int[10];

        // 2.遍历源数组,获取每一个数据,按位放到指定位置
        for (int i = 0; i < arr.length; i++) {
            countArr[arr[i]/exp%10]++;
        }

        // 3.对辅助数组进行加工处理
        for (int i = 1; i < countArr.length; i++) {
            countArr[i] += countArr[i-1];
        }

        // 5.倒序遍历源数组
        // 已排序数组和待排序数组同样长
        int[] sortedArr = new int[arr.length];
        for (int i = arr.length-1; i >= 0; i--) {
            // 从源数组中取出数据
            int num = arr[i];
            sortedArr[countArr[num/exp%10] - 1] = num;
            // 辅助数组中该数据的数量减一,也就是后续相同数据放到前面一个位置
            countArr[num/exp%10]--;
        }

        // 6.将已排序的数据放到待排序的数组中
        for (int i = 0; i < sortedArr.length; i++) {
            arr[i] = sortedArr[i];
        }
    }
}

基数排序的方式

基数排序的方式能够分为LSDMSD两种:blog

  1. LSD最低位优先(Least Significant Digit first)法,简称LSD法:先从最低(最右边)位开始排序,再对倒数第二低位进行排序,依次重复,直到对最高位排序后便获得一个有序序列。咱们上面的案例就是先按个位排序,再按十位排序就属于最低位优先(LSD)
  2. MSD最高位优先(Most Significant Digit first)法,简称MSD法:先从最高位(最左边)开始排序,再对第二高位进行排序,依次重复,直到对最低位排序后便获得一个有序序列。

基数排序的复杂度

空间复杂度:每位进行排序时,须要一个长度为10的辅助数组来统计出现的次数,还须要一个长度和待排序数组同样的数组来存放当前当前此次计数排序的结果,因此空间复杂度为O(n) 时间复杂度:1.获取数组中最大元素操做次数n,2.遍历源数组,获取每一个数据,按位放到指定位置操做次数n,3.对辅助数组进行加工处理操做次数10,4.倒序遍历源数组进行排序操做次数n,5.将已排序的数据放到待排序的数组中操做次数n,总的操做次数为:4n+10,因此总的时间复杂度为O(n)。排序

总结

基数排序(Radix Sort)是计数排序的扩展,它的基本思想是:将整数按位数分割成不一样的数字,而后按每一个位数分别比较。 具体作法是:将全部待排序数值(正整数)统一为一样的数位长度,数位较短的数前面补零。而后从最低位开始,依次进行排序。这样从最低位排序一直到最高位排序完成之后, 数列就变成一个有序数列。

基数排序的方式能够分为LSDMSD两种。


原创文章和动画制做真心不易,您的点赞就是最大的支持! 想了解更多文章请关注微信公众号:表哥动画学编程

相关文章
相关标签/搜索