目录
1.基本思想
(1)创建一个新的数组,数组的大小K = 原数组中的最大值(max) - 最小值(min) + 1,用于统计相同元素出现的次数。
(2)根据统计的结果按数组下标的顺序返回到原来数组中。
2.计数排序的特征
(1)计数排序适用于范围较为集中且重复数据较多的场景,效率很高。
(2)计数排序只适合对整数进行排序。
(3)先遍历一边原数组,找到最大值和最小值,再遍历一遍原数组统计相同元素次数,最后再把统计好的遍历一边,放回原数组中完成排序,所以时间复杂度为O(N)。
(4)空间复杂度:O(K)。
3.计数排序的基本步骤
(1)遍历一遍原数组,找到数组中的最大值(max)和最小值(min)。
(2)利用找到的最大值和最小值,开一个新数组,用于存储相同元素出现的次数,新数组的大小K = max - min + 1。
(3)遍历一边原数组,统计相同元素出现的次数,并把次数存储到新数组中对于的位置。
(4)根据统计的结果按数组下标的顺序返回到原来数组中。
4.计数排序算法实现
void CountSort(int* a, int n)
{
//确定数组中的最大值和最小值
int max = a[0];
int min = a[0];
for (int i = 1; i < n; i++)
{
if (a[i] > max)
{
max = a[i];
}
if (a[i] < min)
{
min = a[i];
}
}
//用最大值和最小值确定范围,用范围大小开数组
int range = max - min + 1; //闭区间计算个数: 右 - 左 + 1
int* arr = (int*)calloc(range, sizeof(int)); //存每个数组出现的次数
if (arr == NULL)
{
perror("calloc fail!\n");
exit(1);
}
//统计相同元素出现的次数
for (int j = 0; j < n; j++)
{
//真实值减去相对值 = 数组下标,该数组下标对应的值+1
//int tmp = a[j] - min;
//arr[tmp]++;
arr[a[j] - min]++;
}
// 排序
int z = 0;
for (int i = 0; i < range; i++) //arr数组从0到 range - 1
{
while (arr[i]--) //返回arr[i]次 i + min
{
a[z] = i + min;
z++;
}
}
free(arr);
arr = NULL;
}