一、计数排序的介绍
计数排序实现是将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是O(n+k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。
计数排序的实现步骤如下:
(1)找出待排序的数组中最大和最小的元素
(2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项
(3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
基本思想:
计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。
二、代码实现
代码如下(示例):
#include<stdio.h>
#include<string.h>
#include<time.h>
#include<stdlib.h>
void CountSort(int* a, int n)
{
int min = a[0], max = a[0];
for (size_t i = 0; i < n; i++)
{
if (a[i] < min)
min = a[i];
if (a[i] > max)
max = a[i];
}
int range = max - min + 1;
int* count = (int*)malloc(sizeof(int) * range);
printf("range:%d\n", range);
if (count == NULL)
{
perror("malloc fail");
return;
}
memset(count, 0, sizeof(int) * range);
for (int i = 0; i < n; i++)
{
count[a[i] - min]++;
}
// 排序
int j = 0;
for (int i = 0; i < range; i++)
{
while (count[i]--)
{
a[j++] = i + min;
}
}
}
//打印数组
void PrintArray(int* a, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
int main()
{
int a1[] = {12,7,3,9,9,6,5,7,9,8,6};
CountSort(a1, sizeof(a1) / sizeof(int));
PrintArray(a1, sizeof(a1) / sizeof(int));
return 0;
}
三、计数排序的分析
计数排序的复杂度分析:
- 时间复杂度:O(n+k)
- 空间复杂度:O(n+k)
优点:
1.计数排序不会改便数据原有的位置,因此它是稳定的排序。
2.计数排序的速度比较其他排序的速度快。
缺点:
1.计数排序只适用于有范围的整数对数据类型有要求。
2.当数据范围过大时,计数排序会开辟较大的空间会浪费空间。
以上就是对计数排序的代码实现和分析,以上数据仅供参考。