1、时间复杂度:o(n);
空间复杂度:o(n+k);
牺牲空间复杂度换取时间复杂度的降低;
2、算法思想:
计数排序局限性比较大,算法思想:假定输入是有一个小范围内的整数构成的(比如年龄等),利用额外的数组去记录元素应该排列的位置,思想比较简单。
计数排序是典型的不是基于比较的排序算法,基于比较的排序算法最少也要O(nlogn),有没有可能创造线性时间的排序算法呢?那就是不基于比较的排序算法;
如果数组的数据范围为0~100,则很适合此算法。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。它只能对整数进行排序
算法步骤:
1、找出待排序的数组中最大和最小的元素
2、统计数组中每个值为i的元素出现的次数,存入数组C的第i项
3、对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
4、反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
实现代码:
/***************************************************************************
* @file main.cpp
* @author MISAYAONE
* @date 27 March 2017
* @remark 27 March 2017
* @theme Counting Sort
***************************************************************************/
#include <iostream>
#include <vector>
#include <time.h>
#include <Windows.h>
using namespace std;
void Counting_sort(int a[], size_t n, int k)
{
//申请额外空间
int *p = new int[n];
int *q = new int[k+1];
for (int i = 0; i < k; ++i)
{
q[i] = 0;//将q指向的数组所有元素置0
}
//保存数组a中每个元素出现的个数,将排序交给了q数组(其顺序在q数组中就是有序的)
for (int j = 0; j < n; ++j)
{
q[a[j]]++ ;
}
//将所有计数次数累加
for (int i = 1; i < k; ++i)
{
q[i] = q[i] + q[i-1];
}
//将元素重新输入
for (int i = n-1; i >= 0; --i)
{
//次数大小最小为1、数组开始为0
p[q[a[i]]-1] = a[i];
q[a[i]]--;
}
for (int j = 0; j < n; ++j)
{
a[j] = p[j];
}
//不要忘了释放分配的空间
delete []p;
delete []q;
}
int main(int argc, char **argv)
{
int a[10] = {2,56,4,2,9,56,3,59,9,16};
int max = a[0];
for (int i = 1;i < 10; ++i)
{
if (a[i]>max)
{
max = a[i];
}
}
Counting_sort(a,10,max+1);//传入max+1是为了让计数的数组从0开始足够大
for (int i = 0; i < 10; ++i)
{
cout<<a[i]<<" ";
}
cin.get();
return 0;
}