要点

基数排序与本系列前面讲解的七种排序方法都不同,它不需要比较关键字的大小

它是根据关键字中各位的值,通过对排序的N个元素进行若干趟“分配”与“收集”来实现排序的。

不妨通过一个具体的实例来展示一下,基数排序是如何进行的。

设有一个初始序列为: R {50, 123, 543, 187, 49, 30, 0, 2, 11, 100}。

我们知道,任何一个阿拉伯数,它的各个位数上的基数都是以0~9来表示的。

所以我们不妨把0~9视为10个桶。

我们先根据序列的个位数的数字来进行分类,将其分到指定的桶中。例如:R[0] = 50,个位数上是0,将这个数存入编号为0的桶中。

分类后,我们在从各个桶中,将这些数按照从编号0到编号9的顺序依次将所有数取出来。

这时,得到的序列就是个位数上呈递增趋势的序列。

按照个位数排序: {50, 30, 0, 100, 11, 2, 123, 543, 187, 49}。

接下来,可以对十位数、百位数也按照这种方法进行排序,最后就能得到排序完成的序列。

完整参考代码

1LSD法实现

实现代码

package notes.javase.algorithm.sort;
 
public class RadixSort {
 
    // 获取x这个数的d位数上的数字
    // 比如获取123的1位数,结果返回3
    public int getDigit(int x, int d) {
        int a[] = {
                1, 1, 10, 100
        }; // 本实例中的最大数是百位数,所以只要到100就可以了
        return ((x / a[d]) % 10);
    }
 
    public void radixSort(int[] list, int begin, int end, int digit) {
        final int radix = 10; // 基数
        int i = 0, j = 0;
        int[] count = new int[radix]; // 存放各个桶的数据统计个数
        int[] bucket = new int[end - begin + 1];
 
        // 按照从低位到高位的顺序执行排序过程
        for (int d = 1; d <= digit; d++) {
 
            // 置空各个桶的数据统计
            for (i = 0; i < radix; i++) {
                count[i] = 0;
            }
 
            // 统计各个桶将要装入的数据个数
            for (i = begin; i <= end; i++) {
                j = getDigit(list[i], d);
                count[j]++;
            }
 
            // count[i]表示第i个桶的右边界索引
            for (i = 1; i < radix; i++) {
                count[i] = count[i] + count[i - 1];
            }
 
            // 将数据依次装入桶中
            // 这里要从右向左扫描,保证排序稳定性
            for (i = end; i >= begin; i--) {
                j = getDigit(list[i], d); // 求出关键码的第k位的数字, 例如:576的第3位是5
                bucket[count[j] - 1] = list[i]; // 放入对应的桶中,count[j]-1是第j个桶的右边界索引
                count[j]--; // 对应桶的装入数据索引减一
            }
 
            // 将已分配好的桶中数据再倒出来,此时已是对应当前位数有序的表
            for (i = begin, j = 0; i <= end; i++, j++) {
                list[i] = bucket[j];
            }
        }
    }
 
    public int[] sort(int[] list) {
        radixSort(list, 0, list.length - 1, 3);
        return list;
    }
 
    // 打印完整序列
    public void printAll(int[] list) {
        for (int value : list) {
            System.out.print(value + "\t");
        }
        System.out.println();
    }
 
    public static void main(String[] args) {
        int[] array = {
                50, 123, 543, 187, 49, 30, 0, 2, 11, 100
        };
        RadixSort radix = new RadixSort();
        System.out.print("排序前:\t\t");
        radix.printAll(array);
        radix.sort(array);
        System.out.print("排序后:\t\t");
        radix.printAll(array);
    }
}

运行结果

排序前:     50  123 543 187 49  30  0   2   11  100
排序后:     0   2   11  30  49  50  100 123 187 543 

算法分析

基数排序的性能

排序类别

排序方法

时间复杂度

空间复杂度

稳定性

复杂性

平均情况

最坏情况

最好情况

基数排序

基数排序

O(d(n+r))

O(d(n+r))

O(d(n+r))

O(n+r)

稳定

较复杂

时间复杂度

通过上文可知,假设在基数排序中,r为基数,d为位数。则基数排序的时间复杂度为O(d(n+r))

我们可以看出,基数排序的效率和初始序列是否有序没有关联。

空间复杂度

在基数排序过程中,对于任何位数上的基数进行“装桶”操作时,都需要n+r个临时空间。

算法稳定性

在基数排序过程中,每次都是将当前位数上相同数值的元素统一“装桶”,并不需要交换位置。所以基数排序是稳定的算法。

转载于:https://www.cnblogs.com/yk123/p/8341184.html

算法8-排序-基数排序相关推荐

  1. 看动画学算法之:排序-基数排序

    文章目录 简介 基数排序的例子 基数排序的java代码实现 基数排序的时间复杂度 简介 之前的文章我们讲了count排序,但是count排序有个限制,因为count数组是有限的,如果数组中的元素范围过 ...

  2. js排序算法详解-基数排序

    全栈工程师开发手册 (作者:栾鹏) js系列教程5-数据结构和算法全解 js排序算法详解-基数排序 其实基数排序和桶排序挺类似的,都是找一个容器把属于同一类的元素装起来,然后进行排序.可以把基数排序类 ...

  3. 排序算法九:基数排序

    排序算法九:基数排序 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 引言 在我的博文<"主宰世界"的10种算法短评>中给出的 ...

  4. 三种线性排序算法 计数排序、桶排序与基数排序-BYVoid

    转自:BYVoid [非基于比较的排序] 在计算机科学中,排序是一门基础的算法技术,许多算法都要以此作为基础,不同的排序算法有着不同的时间开销和空间开销.排序算法有非常多种,如我们最常用的快速排序和堆 ...

  5. 三种线性排序算法 计数排序、桶排序与基数排序—— 转自:BYVoid

    三种线性排序算法 计数排序.桶排序与基数排序 [非基于比较的排序] 在计算机科学中,排序是一门基础的算法技术,许多算法都要以此作为基础,不同的排序算法有着不同的时间开销和空间开销.排序算法有非常多种, ...

  6. 十大经典排序算法详解(三)-堆排序,计数排序,桶排序,基数排序

    养成习惯,先赞后看!!! 你的点赞与关注真的对我非常有帮助.如果可以的话,动动手指,一键三连吧!!! 十大经典排序算法-堆排序,计数排序,桶排序,基数排序 前言 这是十大经典排序算法详解的最后一篇了. ...

  7. 排序算法10——图解基数排序(次位优先法LSD和主位优先法MSD)

    排序算法1--图解冒泡排序及其实现(三种方法,基于模板及函数指针) 排序算法2--图解简单选择排序及其实现 排序算法3--图解直接插入排序以及折半(二分)插入排序及其实现 排序算法4--图解希尔排序及 ...

  8. JavaScript实现十种经典排序算法(js排序算法)

    冒泡排序算法 冒泡排序(Bubble Sort)是一种简单直观的排序算法.冒泡排序算法的步骤描述如下: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一 ...

  9. 时间复杂度为on的排序算法_排序算法amp;时间复杂度计算

    对于排序算法而言,有几个重要的点: 理解此种排序算法是怎么运行的 理解算法的时间复杂度与空间复杂度计算 递推公式(关乎时间复杂度的计算) 递推公式主要为以下的形式(递归使用的复杂度也这么算): 具体推 ...

  10. python算法题排序_python-数据结构与算法- 面试常考排序算法题-快排-冒泡-堆排-二分-选择等...

    算法可视化网站推荐---->visualgo 0.面试题中的排序算法 一些排序算法可能在工作中用的会比较少,但是面试却是不得不面对的问题.算法有助于提高我们对数据结构的理解以及提高自己的逻辑能力 ...

最新文章

  1. 决策树算法(二)——构建数据集
  2. 50岁,他希望自己还可以写代码
  3. 2.14 文件和目录权限chmod
  4. QT的QScriptable类的使用
  5. 使用调试器进行事后跟踪
  6. (0.3)HarmonyOS鸿蒙开发工具DevEco Studio 模拟器使用
  7. Mschart图表制作
  8. ajax 折叠,ASP.NET AJAX可折叠面板Accordion应用实例
  9. win7系统office向程序发送命令时出现错误
  10. matlab 局部图放大或缩小
  11. Spring_day2
  12. 两天,我把分布式事务搞完了!
  13. 未能加载文件或程序集 CrystalDecisions.Web Version=10.2.3600解决方法
  14. Nmap内网扫描端口
  15. 计算混响时间的意义_大盘点:混响时间常用的几种计算公式
  16. 计算机组装系统安装系统,刚组装电脑怎么装系统?
  17. bash 单引号 双引号_Bash Shell中的单引号和双引号有什么区别?
  18. peoplesoft 调用Java_利用 XML Publisher 创建 PeopleSoft 报表
  19. 51制作贪吃蛇小游戏,附带Proteus仿真
  20. Bugku web — ereg正则%00截断(代码审计) ——详细题解

热门文章

  1. Flutter之Redux框架原理解析
  2. Android-Universal-Image-Loader学习笔记(一)
  3. php使用循环语句输出二位数组,PHP中遍历二维数组—以不同形式的输出操作
  4. bufferedreader读取中文乱码_Python OpenCV与中文相关的三个常见问题
  5. linux ftp指定下载文件名称,linux中通过FTP下载指定的文件方法linux网页制作 -电脑资料...
  6. 查看谁连接oracle,oracle如何查看当前有哪些用户连接到数据库
  7. github可以刷星吗_国内某知名社区居然也在GitHub上玩起了刷星活动
  8. python 线程-threding示例使用
  9. 史上最全的面试宝典,让你轻松入职
  10. 构建安全可控的网络环境,国产化网管势在必行