计数排序:
原理
先把每个元素的出现次数算出来,然后算出该元素所在最终排好序列中的绝对位置(最终位置),再依次把初始序列中的元素,根据该元素所在最终的绝对位置移到排序数组中。
性能
时间复杂度为O(N+K),空间复杂度为O(N+K),算法是稳定的,与初始序列无关,不需要进行比较就能排好序的算法。
使用场景
算法只能使用在已知序列中的元素在0-k之间,且要求排序的复杂度在线性效率上。
代码
//计数排序
void count_sort(int arr[],int sorted_arr[],int len,int k)
{
//数组中的元素大小为0-k,
//先统计每个数的相对位置,再算出该数所在序列中排序后的绝对位置
int *count_arr = (int*)malloc(sizeof(int)*(k+1));
for (int i = 0; i <= k; i++)
{ count_arr[i] = 0; }
for (int i = 0; i < len; i++)
{ //每个元素的相对位置 count_arr[arr[i]]++; }
for (int i = 1; i <= k; i++){
//每个元素的绝对位置,位置为第1个到n个
count_arr[i] += count_arr[i - 1]; }
for (int i = len-1; i >=0; i--){
//从后往前,可使排序稳定,相等的俩个数的位置不会发 生逆序
count_arr[arr[i]]--; //把在排序后序列中绝对位置为1-n的数依次放入到0- (n-1)中
sorted_arr[count_arr[arr[i]]] = arr[i];
}
free(count_arr); }
桶排序
原理
根据待排序列元素的大小范围,均匀独立的划分M个桶
将N个输入元素分布到各个桶中去
再对各个桶中的元素进行排序
此时再按次序把各桶中的元素列出来即是已排序好的。

性能
时间复杂度为O(N+C),O(C)=O(M(N/M)log(N/M))=O(NlogN-NlogM),空间复杂度为O(N+M),算法是稳定的,且与初始序列无关。
使用场景
算法思想和散列中的开散列法差不多,当冲突时放入同一个桶中;可应用于数据量分布比较均匀,或比较侧重于区间数量时。
基数排序
原理
对于有d个关键字时,可以分别按关键字进行排序。有俩种方法:
MSD:先从高位开始进行排序,在每个关键字上,可采用计数排序
LSD:先从低位开始进行排序,在每个关键字上,可采用桶排序

性能
时间复杂度为O(d*(N+K)),空间复杂度为O(N+K)。
原理
根据待排序列元素的大小范围,均匀独立的划分M个桶
将N个输入元素分布到各个桶中去
再对各个桶中的元素进行排序
此时再按次序把各桶中的元素列出来即是已排序好的。

性能
时间复杂度为O(N+C),O(C)=O(M(N/M)log(N/M))=O(NlogN-NlogM),空间复杂度为O(N+M),算法是稳定的,且与初始序列无关。
使用场景
算法思想和散列中的开散列法差不多,当冲突时放入同一个桶中;可应用于数据量分布比较均匀,或比较侧重于区间数量时。
基数排序
原理
对于有d个关键字时,可以分别按关键字进行排序。有俩种方法:
MSD:先从高位开始进行排序,在每个关键字上,可采用计数排序
LSD:先从低位开始进行排序,在每个关键字上,可采用桶排序

性能
时间复杂度为O(d*(N+K)),空间复杂度为O(N+K)。