一:什么是非比较排序
众所周知,排序有很多种办法,其中无非就是比较数组中的值,另一种就是一种分配的思想,类似于一个萝卜一个坑,这也就是非比较排序。
二:有哪些非比较排序呢?
可以分为三大类 计数排序 、 基数排序 、 桶排序 。这是比较常见的三种排序方式,当然核心思想都是 一个萝卜一个坑。
三:具体实现
1:计数排序
顾名思义,计数排序的核心思想就是统计待排序数组中,每个数出现的次数,使用另一个数组来记录致谢数据,等遍历一遍待排序数组之后,所有的数据的出现次数都记录了下来,再根据记录的数组进行还原。
这里记录数组的大小为待排序数组的最大值减去最小值,当某个元素出现一次,则在固定的下标出执行+1。
时间复杂度分析:遍历待排序数组 o(n) 第二遍遍历记录数组 o(range) 还原数组o(n) 故时间复杂度是o(n+range+n)
Java代码实现如下
//计数排序
public static void CountingSorting(int[] array)
{
int max=array[0];
int min=array[0];
//找到数组中的范围
for (int i = 0; i < array.length; i++) {
if (array[i]>max)
{
max=array[i];
}
if (array[i]<min)
{
min=array[i];
}
}
//构建统计用的数组
int[] tempory=new int[max-min+1];
System.out.println(tempory.length+"--"+max+"---"+min);
for (int i = 0; i < array.length; i++) {
tempory[array[i]-min]++;
}
//写回到原数组
int j=0;
for (int i = 0; i < tempory.length; i++) {
while (tempory[i]>0)
{
array[j++]=i+min;
tempory[i]--;
}
}
System.out.println(Arrays.toString(array));
}
2:基数排序
是 简单来说就是根据待排序序列的位来决定的,分别设置10个桶,然后分别对待排序的数进行取个位 十位,白位等等,放到对应的桶之中,每经历一遍,依次从桶之中拿出数据,再对新的待排序列进行操作,这时候就是取百分位了,每次都会上升一个数量级。
Java代码
//基数排序
public static void CardinalitySort(int[] array)
{
//数组实现
//先找到数组中的元素的最大值,确定最大的位数
int max=array[0];
for (int i = 0; i < array.length;i++) {
if (array[i]>max)
{
max=array[i];
}
}
//计算位数
int time=0;
while (max>0)
{
max/=10;
time++;
}
//创建10个队列
ArrayList<Integer>[] list=new ArrayList[10];
for (int i = 0; i < 10; i++) {
list[i]=new ArrayList<Integer>();
}
//开始循环
for (int j = 0; j < time; j++)
{
for (int i = 0; i <array.length ; i++)
{
list[ array[i] % (int)Math.pow(10, j+1) / (int)Math.pow(10, j) ] .add(array[i]);
if (j!=0)
{
Integer s=new Integer(array[i]);
list[array[i] % (int) Math.pow(10, j) / (int) Math.pow(10, j - 1)].remove(s);
}
}
int temp2=0;
for (int i = 0; i < 10; i++)
{
for (int k = 0; k < list[i].size(); k++)
{
array[temp2++]=list[i].get(k);
}
}
}
System.out.println(Arrays.toString(array));
}
2:桶排序
桶排序比较类似于上两个排序方式,不过桶类似于分治法,讲一个大的待排序数组分为多个桶内,再对多个桶中的序列进行排序。
实现代码:
//桶排序
//这里桶之中的数据,我们调用快速排序进行排序
public static void BucketSort(int[] array)
{
//先找到范围
int max=0,min=0;
for (int i = 0; i <array.length; i++) {
if (array[i]>max)
{
max=array[i];
}
if (array[i]<min)
{
min=array[i];
}
}
int range=max-min;
//分为几个桶这里取range/10 最小桶从min开始 到最大桶的max
int bucketNum=range/10;
int [][] bucket=new int[10][array.length];
//记录桶之中的数据量
int[] BucteDatetnum=new int[10];
//这里放入桶之中
for (int i = 0; i <array.length ; i++) {
int index=(array[i]-min)/10;
System.out.println("index"+"=="+index);
bucket[index] [BucteDatetnum[index]] =array[i];
BucteDatetnum[index]++;
}
//分别对每个桶进行快速排序
for (int i = 0; i <10 ; i++) {
QuickSort(bucket[i],0,BucteDatetnum[i]);
System.out.println(Arrays.toString(bucket[i]));
}
}