算法熟记-排序系列-计数排序
1. 简述
计数排序的排序对象一般是整数。
假设待排序数组为 int array[], 数组长度为n。
第一步,遍历数组,得到数组的最大值max和最小值min。 (n)
第二步,开辟一个新数组,int count[],数组长度为max-min+1,其中每个元素初始化为0。
第三步,遍历array数组,在count数组内统计array中每个元素出现的个数。(n)
第四步,根据count数组,填充array数组。(n+k)
2. 复杂度
假设array中的数值范围是k,其中k=max-min+1,那么时间复杂度是O(n+k),实际上这个复杂度算的是第四步的时间复杂度,四个步骤中,遍历元素的次数应该是n+n+n+k=3*n+k。
空间复杂度是O(k),当array中的数值范围很大的时候,会使用很大的额外空间。对于char这样的数据类型,计数排序还是很好用的。
稳定性属于稳定的排序。
3. 代码
void counting_sort(int array[], int n) {
// 得到数值范围
int max = array[0];
int min = array[0];
for(int i=1; i<n; i++) {
if(array[i] > max)
max = array[i];
else if(array[i] < min)
min = array[i];
}
// 开辟辅助空间
int range = max-min+1;
int* count = new int[range];
for(int i=0; i<range; i++)
count[i] = 0;
// 计数过程
for(int i=0; i<n; i++)
count[array[i]-min]++;
// 反向填充
int index = 0; // array的下标
for(int i=min; i<=max && index<n; i++) // 遍历每个数值
for(int j=0; j<count[i-min] && index<n; j++) // 每个数值出现的次数
array[index++] = i;
delete []count;
}
// 得到数值范围
int max = array[0];
int min = array[0];
for(int i=1; i<n; i++) {
if(array[i] > max)
max = array[i];
else if(array[i] < min)
min = array[i];
}
// 开辟辅助空间
int range = max-min+1;
int* count = new int[range];
for(int i=0; i<range; i++)
count[i] = 0;
// 计数过程
for(int i=0; i<n; i++)
count[array[i]-min]++;
// 反向填充
int index = 0; // array的下标
for(int i=min; i<=max && index<n; i++) // 遍历每个数值
for(int j=0; j<count[i-min] && index<n; j++) // 每个数值出现的次数
array[index++] = i;
delete []count;
}
4. 参考资料