您的位置:首页 > 其它

算法导论 第八章计数排序(counting sort)

2011-02-21 14:06 302 查看
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
//待排数据在[0,k]范围内,也可以改变上下界,不过要注意一定让
//这个范围的大小大于或等于待排数据的范围,也可以把k+1理解过为
//待排数据的种类数。数组下标从1开始,length是数据总量,k是数据
//种类
void CountingSort(int A[] , int length , int B[] , int k)
{
int *C = new int[k];

//初始化,将所有统计数据记为0。
for(int i=0 ; i<=k ; i++)//i从0开始似乎也行
{
C[i] = 0;
}

//开始统计在[0,k]范围内的每一种数据出现的次数
for(int j=1 ; j<=length ; j++)
{
C[A[j]] = C[A[j]]+1;
}

//进过一个由左向右,当前元素与它前一个元素相加
//并保留在当前位置上,这个过程执行之后,C[i]保
//存的是数组A中小于或等于i的数据的数目。
for(int i=1 ; i<=k ; i++)
{
C[i] += C[i-1];
}
for(int j=length ; j>=1 ; j--)
{
B[C[A[j]]] = A[j];//有C[A[j]]个数是小于或等于A[j]的,
//把A[j]安排在第C[A[j]]个位置上。

C[A[j]]--;        //由于当前数据的位置已经安排好,
//当后面遇到小于或等于A[j]的数据
//只能安排在当前位置的前一个位置了,
//所以这里减1。
}
}
int main()
{
const int n = 1000;
int A
,B
;
int length = n-1;
for(int i=0 ; i<n ; i++)
{
A[i] = rand()%100;
}
CountingSort(A , length , B , 100);
for(int i=0 ; i<n ; i++)
{
cout <<B[i] << ' ';
}
return 0;
}


看最后一个for循环,循环变量是从length减到1,而位置的安排也是从后往前的,所以下标小的元素的位置总是较早地被安排,因此计数排序是一种稳定的排序。

计数排序的时间按复杂度为O(n+k),因此k=O(n),即k远小于数据量n时,复杂度为O(n),用计数排序能够得到一个很好的效果。

这个算法的优点是排序快,缺点是需要额外的空间,而且对数据的种类k的上界有要求。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: