Java排序算法总结之(五)—— 基数排序

来源:互联网 发布:淘宝集运送在哪里 编辑:程序博客网 时间:2024/04/29 05:49

排序方法可以分为两种:内部排序 和 外部排序

内部排序的方法很多,常用的大致可以分为:

  1. 插入排序(直接插入排序、折半插入排序、希尔排序)
  2. 交换排序(冒泡排序、快速排序)
  3. 选择排序(简单选择排序、堆排序)
  4. 归并排序
  5. 基数排序

基数排序

基本思想:与之前各种排序算法需要比较和移动不同,基数排序不需要比较,只通过关键字分类来完成排序。

比如一个序列有 n 个数据 {R1,R2,R3,…,Rn},每个数据含有 k 个关键字 Ri = (Ai,Bi,Ci,Di…),对其排序需要分别考虑 k 个关键字。比如定义一个整型数组,元素的每一位都可以看成一个关键字。

<span style="font-size:18px;">int[] array = { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4};</span>
首先建立一个二维数组:

0    1    2    3    4    5    6    7    8    9    

先对array按照个位(第一个关键字)分类,放入数组中:

0    1    212   313   434644 5655  676   79727  83878  94949  分类后按行读取到数组中,数组变为:

<span style="font-size:18px;">array = { 12,13,34,64,4,65,5,76,97,27,38,78,49,49};</span>

接着对数组中的十位(第二个关键字)进行分类:

045  11213  227   33438  44949  5    66465  77678  8    997   继续读取到数组中,即可完成分类:

<span style="font-size:18px;">array = { 4,5,12,13,27,34,38,49,49,64,65,76,78,97};</span>
同时也能看出,基数分类是稳定的。

Java代码:

public class RadixSort {public static int[] sort(int[] s) {int[][] bucket = new int[10][s.length];// 二维数组分类存放,行:0 ~ 9,列:存放对应该位的数的个数int n = 1;// 获取某一位,从最低位开始int[] col = new int[s.length];// 存放当前位 的 数字 的 个数,即二维数组在这一行的列数int count = 1;// 按照每一位排序,排序次数计数int k = 0;// 保存每一位排序后的结果到数组 s 中,用于下一位的排序输入int digit_num = RadixSort.getMaxDigit(s);// 获取数列中最多的位数,并以此为准while (count <= digit_num) {for (int num : s) {// 将s中的数据根据当前digit分类,存入bucket数组中int digit = (num / n) % 10;bucket[digit][col[digit]] = num;col[digit]++;}for (int i = 0; i < s.length; i++) {// 依次遍历bucket的每一行if (col[i] != 0) {// 当前行的数据不为0for (int j = 0; j < col[i]; j++) {// 将当前行的数据更新到数组s中s[k] = bucket[i][j];k++;}}col[i] = 0;// 要把当前列数清零}n *= 10;count++;k = 0;}return s;}// 静态方法中不能调用非静态方法private static int getMaxDigit(int[] s) {int d = 1;int max = 0;for (int i = 0; i < s.length; i++) {if (s[i] > max)max = s[i];}while (max / 10 != 0) {d++;max = max / 10;}return d;}}

效率分析:

基数排序的时间复杂度是O(k·n),其中n是排序元素个数,k是数字位数。

k的大小取决于数字位的选择(比如比特位数),和待排序数据所属数据类型的全集的大小;k决定了进行多少轮处理,而n是每轮处理的操作数目。



0 0
原创粉丝点击