计数排序
基本借鉴与<<算法导论>>第三版
- 计数排序的基本思想
对于每一个元素x,确定小于x的元素个数。利用这一信息,就可以直接把x放在输出数组中的位置上了。例如,如果有17个元素小于x,则x就应该在第18个输出位置上。 当有几个元素相同时,这一方案要略做修改。
代码
#include <iostream>
#include <cstring>
using namespace std;
const int LEN = 12;
void countsort(int output[], int input[], int max){
/*input为输入的数组,output为输出的数组,max为input数组中元素的最大值*/
int *temp = new int[max+1]; // 临时存储空间
memset(temp, 0, sizeof(temp)); // 初始化
int i;
for(i=0; i<LEN; i++){
temp[input[i]]++;
} // 如果一个输入元素的值为x,就将temp[x]的值加一,temp[x]中保存了值为x的元素的个数
for(i=1; i<max+1; i++){
temp[i] += temp[i-1];
} // 计算有多少输入元素是小于或等于x的
for(i=LEN-1; i>=0; i--){
output[temp[input[i]]-1] = input[i];
temp[input[i]]--; // 当遇到下一个值等于input[i]的输入元素(如果存在)时,该元素可以直接被放在输出数组的前一个位置上
} // 把每个元素input[i]放在输出数组output中的正确位置上
delete [] temp;
}
int main(void){
int a[LEN] = {1, 5, 3, 7, 5, 6, 3, 2, 5, 3, 0, 8};
int out[LEN];
countsort(out, a, 8);
int i;
for(i=0; i<LEN; i++)
cout << out[i] << " ";
cout << endl;
return 0;
}
输出
0 1 2 3 3 3 5 5 5 6 7 8
时间复杂度
算法第一和最后一个循环的时间复杂度为O(LEN),第二个循环的时间复杂度为O(max)。所以总的时间代价就是O(LEN+max)。在实际工作中,当max=O(LEN)时,我们一般会采用计数排序,这时的时间复杂度为O(LEN)。