计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。 当然这是一种牺牲空间换取时间的做法,
计数排序的思想是:重新申请一个数组,新数组的大小是由原数组中最大值减去最小值加一得到的,然后将原数组中出现的数字次数存在新数组里,最后通过新数组进行排序。
可能我这样描述有点抽象
例如:我们的数字arr[ ]={1,3,4,2,1,1,3,4,5};
我们开辟一个(5-1+1) 大小的newarr数组,然后遍历arr[ ],因为第一个数是1 ,所以newarr[ 0 ]++;第二个数为3 ,所以newarr[ 2 ]++;一次遍历arr中的数字,当全部遍历完成之后,通过新数组的下标和内容给原数组赋值,所赋的数字就是新数组的下标加上原数组中的最小值。
如果这样该没有理解整个过程,那么我们来看一下代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//计数排序:先根据最大最小值申请连续空间,将所申请空间和最大最小值建立映射关系用于计数,计数完成之后对数组重新进行排序
void CountSort(int arr[],int nLength)
{
if(arr == NULL || nLength <=0)return;
//找到最大值最小值
int i;
int nMin;
int nMax;
nMin = arr[0];
nMax = arr[0];
for(i = 1;i<nLength;i++)
{
if(nMin > arr[i])
{
nMin = arr[i];
}
if(nMax < arr[i])
{
nMax = arr[i];
}
}
//根据最大值 最小值 申请计数数组
int *pCount = NULL;
pCount = (int*)malloc(sizeof(int)*(nMax-nMin+1));
memset(pCount,0,sizeof(int)*(nMax-nMin+1));
//计数
for(i = 0;i<nLength;i++)
{
pCount[arr[i]-nMin]++;
}
//排序
int j = 0;
for(i = 0;i<nMax-nMin+1;i++)
{
while(pCount[i] != 0)
{
arr[j] = i+nMin;
j++;
pCount[i]--;
}
}
free(pCount);
pCount = NULL;
}
int main()
{
int arr[] = {1,4,3,3,2,5,8,8,1};
CountSort(arr,sizeof(arr)/sizeof(arr[0]));
int i;
for(i = 0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
该排序的适用场合:要求元素在一个区间范围内,并且出现的频率高。