非比较排序:
比较排序是基于输入元素间的比较。任意一个比较排序算法在最坏情况下需要比较的次数至少为nlogn。所以说快速排序,堆排序,归并排序都是渐进最优的排序算法。他们的最坏情况时间复杂度为O(nlogn)。
非比较排序不是基于元素间比较的。包括:桶排序,基数排序,计数排序。
桶排序:
属于非原址排序。
(1)思路:
假定:输入是由一个随机过程产生的[0, 1)区间上均匀分布的实数。将区间[0, 1)划分为n个大小相等的子区间(桶),每桶大小1/n:[0, 1/n), [1/n, 2/n), [2/n, 3/n),…,[k/n, (k+1)/n ),…将n个输入元素分配到这些桶中,对桶中元素进行排序,然后依次连接桶输入0 ≤A[1..n] <1辅助数组B[0..n-1]是一指针数组,指向桶。
排序过程如图:
(2)复杂度分析:
(2.1)时间复杂度:
n:数组元素个数,m:桶个数。
桶排序的平均时间复杂度为线性的O(n+c),其中c=n*(logn-logm)。如果相对于同样的n,桶数量m越大,其效率越高,最好的时间复杂度达到O(n)。
最好情况: O(n)。
平均情况: O(n+c)。
(2.2)空间复杂度:
桶排序的空间复杂度为O(n+m),如果输入数据非常庞大,而桶的数量也非常多,则空间代价无疑是昂贵的。
(3)稳定性:
桶排序是稳定的。
代码片段:
#include <stdio.h>
#define SIZE 16
#define MAXNUM 100 //桶个数最大值
void bucket_sort(int arr[],int len,int max);
int main()
{
int a[SIZE]={2,5,6,12,4,8,8,6,7,8,8,10,7,6,0,1};
bucket_sort(a,SIZE,12); //12-->元素最大值
return 0;
}
//bucket_sort():桶排序
/*
@param:
arr:待排序数组
len:待排序数组长度
max:待排序数组元素最大值,数组中的元素都落在[0,max]区间
@ret:无
*/
void bucket_sort(int arr[],int len,int max)
{
int count[MAXNUM]; //空间复杂度O(m)
for(int i=0;i<=max;i++)
{
count[i]=0;
}
//遍历待排序数组
for(int i=0;i<len;i++)
{
count[arr[i]]++;
}
int k=0;
printf("排序后: \n"); //桶排序输出
//数组元素范围[0,max]
for(int i=0;i<=max;i++) //时间复杂度O(n+m),外循环m次,内循环共n次
{
for(int j=1;j<=count[i];j++)
{
printf("%d ",i);
arr[k++]=i; //简化的可以原址排序
}
}
printf("\n");
}