先说说计数排序的思想:
计数排序假定待排序的所有元素都是介于0到K之间的整数;计数排序使用一个额外的数组countArray,其中第i个元素是待排序数组array中值等于i的元素的个数。然后根据数组countArray来将array中的元素排到正确的位置。
算法的步骤如下:
稳定性和复杂度:
计数排序是稳定的排序算法;平局时间复杂度、最优时间复杂度和最差时间复杂度都为O(n+k),空间复杂度为O(n+k),其中,n为待排元素个数,k为待排元素的范围(0~k)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#define RANDMAX 10000
void getRandArray(int array[], int size);
void countSort(int array[], int size);
void isSorted(int array[], int size);
int main(int argc, char const *argv[])
{
int size = 0;
scanf("%d", &size);
assert(size > 0);
int *array = (int *)calloc(size, sizeof(int));
getRandArray(array, size);
clock_t begin;
clock_t end;
begin = clock();
countSort(array, size);
end = clock();
//打印排序所花费的时间,在linux下单位为ms
printf("%ld\n", (end - begin) / 1000);
isSorted(array, size);
free(array);
return 0;
}
//利用伪随机数填充数组array
void getRandArray(int array[], int size)
{
assert(array != NULL && size > 0);
srand((unsigned) time(NULL));
int i = 0;
for (i = 0; i < size; ++i) {
//产生RANDMAX以内的伪随机数
array[i] = rand() % RANDMAX;
}
}
//从小到大进行排序
void countSort(int array[], int size)
{
assert(array != NULL && size > 0);
//计数数组,用于统计数组array中各个不同数出现的次数
//由于数组array中的数属于0...RANDMAX-1之间,所以countArray的大小要够容纳RANDMAX个int型的值
int *countArray = (int *) calloc(RANDMAX, sizeof(int));
//用于存放已经有序的数列
int *sortedArray = (int *) calloc(size, sizeof(int));
//统计数组array中各个不同数出现的次数,循环结束后countArray[i]表示数值i在array中出现的次数
int index = 0;
for (index = 0; index < size; ++index) {
countArray[array[index]]++;
}
//统计数值比index小的数的个数,循环结束之后countArray[i]表示array中小于等于数值i的元素个数
for (index = 1; index < RANDMAX; ++index) {
countArray[index] += countArray[index - 1];
}
for (index = size - 1; index >= 0; --index) {
//因为数组的起始下标为0,所以要减一
sortedArray[countArray[array[index]] - 1] = array[index];
//这里减一是为了保证当有多个值为array[index]的元素时,后出现的值为array[index]的元素
//放在后面,也就是为了保证排序的稳定性
--countArray[array[index]];
}
memcpy(array, sortedArray, size * sizeof(int));
free(sortedArray);
free(countArray);
}
//判断数组array是否已经是有序的
void isSorted(int array[], int size)
{
assert(array != NULL && size > 0);
int unsorted = 0;
int i = 0;
for (i = 1; i < size; ++i) {
if (array[i] < array[i - 1]) {
unsorted = 1;
break;
}
}
if (unsorted) {
printf("the array is unsorted!\n");
} else {
printf("the array is sorted!\n");
}
}
计数排序是非比较的排序算法,据说其排序速度要快于任何的比较排序算法(我还未验证,但是在排序100000000个10000以内的数时花费为606毫秒,而C语言的qsort函数则为10802毫秒,由此可见一斑),由于计数排序需要一个计数数组以及一个存放有序数列的数组,故计数排序对内存的要求比较高。原文:http://blog.csdn.net/thinkpad4180nc5/article/details/40146487