基数排序是一种与之前几种排序不同的排序方法,之前的排序是基于关键字排序算法。基数排序属于分配式排序,而且基数排序是稳定排序。以下是基数排序的步骤:假设在一个数组为例,数据中的数据项均小于1000(位数最多是三维)。
1 先对数组中所有的数据项个位进行排序,个位数字0~9,从小到大的顺序进行存放(不比较其他位数字大小),结果存放在一个缓存二维数组里面。
2 在步骤1的基础之上继续对数据项的十位进行排序(数据项不改变步骤1的顺序),继续存放缓存数组中。
3 在步骤2的基础之上继续对百位数字大小进行排序,只考虑百位数字大小,但是需要不改变步骤2的大致顺序。
4 通过以上三个步骤后,将数据从缓存二维数组中复制到原来数组中。
基数排序中采用二维数组作为缓存数组的好处在于二维数组的第一维可以存放前一个步骤的各个位上的数字(0~9),第二维是存放具体数据项。
以上步骤可以下图表示:
下面是常见的采用二维数组作为缓存数据进行基数排序的代码:
public static void basicSortAdvanced(int[] number,int numLength)
{
int k=0;
int n=1;
int m=1;
int[][] temp=new int[10][number.length];
int[] order=new int[10];
while(m<=numLength)
{
for(int i=0;i<number.length;i++)
{
int tempVal=(number[i]/n)%10;
temp[tempVal][order[tempVal]]=number[i];
order[tempVal]++;
}
for(int i=0;i<number.length;i++)
{
if(order[i]!=0)
{
for(int j=0;j<order[i];j++)
{
number[k]=temp[i][j];
k++;
}
order[i]=0;
}
}
n*=10;
k=0;
m++;
}
}
关于基数排序的难点
一开始写基数排序时候对于解决保持之前的顺序时,采用二维数组能够巧妙解决这个问题,尝试使用链表以及多个数组解决此问题,但是会引入多个数据结构,会占用较多内存。此处引入二维数组效率较高。
下面是随机数组创建:
int[] array=null;
LinkedList<Integer> link=new LinkedList<Integer>();
public BasicNumberSort(int n)
{
System.out.println("排序之前数组是:");
array=new int[n];
for(int i=0;i<n;i++)
{
array[i]=(int)(Math.random()*1000);
System.out.print(array[i]+" ");
}
System.out.println();
}
测试以及结果:
BasicNumberSort a=new BasicNumberSort(10);
basicSortAdvanced(array, 3);
System.out.println("排序之后数组是:");
show();
排序之前数组是:
161 671 90 606 288 603 368 313 217 525
排序之后数组是:
90 161 217 288 313 368 525 603 606 671
关于基数排序的效率
基数排序,这里的基数是以10为单位,对数据项的各个位进行排序。在基数排序过程中会有较多的复制次数,10个数据项会产生20次复制。复制的次数与数据项的个数成正比,O(N)。这个效率较高,但是随着数据项的个数增多,此时算法的执行效率会降低到O(N*logN),这个效率与快速排序算法相同。