您的位置:首页 > 其它

排序算法(五)-- 线性时间排序之计数排序

2014-10-08 01:00 441 查看

计数排序

计数排序假设n个输入元素中的每一个都是介于0到k之间的整数,此处k为某个整数。当k = O(n)时,计数排序的运行时间为O(n).

计数排序的基本思想是:对于每一个输入元素x,确定小于x的元素个数。利用这一信息,就可以直接把x放到输出数组中的位置上了。例如,如果有17个元素小于x则x就应该放在第18个位置上。当有几个元素相同时,这个方案要改,因为不能把他们放在同一个输出位置上。

在计数排序算法的代码中,假设输入是一个数组A[1 .. n]. 还需要数组B[1.. n]存放排序的输出,C[0 .. k]提供临时存储空间。

算法如下:



这里注意C数组,第一个for循环中为C申请k个空间并且置零,第二的for循环中,C记录了A数组中每个元素出现的个数,第三个for循环中,利用C,记录了A中每个元素最后一次出现的位置。第四个for循环中当元素依次取出是,C中表示A中相应元素位置的C[i]中的元素个数依次减1. 直到B中的元素放满。

程序代码:
/*
线性时间排序 -- 计数排序算法
*/

#include<iostream>
#include<stdlib.h>

using namespace std;

//函数声明
void CountingSort(int A[], int B[], int k);

void main()
{
int A[21];
int B[21];
//待排序数组
cout<<"待排序数组"<<endl;
for(int i = 1; i <= 20; i++)
{
A[i] = rand()%10;
cout<<A[i]<<" ";
}
cout<<endl;

// 排序
CountingSort(A,B,10);

// 输出排序结果
cout<<"排序结果"<<endl;
for(int j = 1; j <= 20; j++)
{
cout<<B[j]<<" ";
}
cout<<endl;
}

//计数排序
void CountingSort(int A[], int B[], int k)
{
int* C = new int[k];
//初始化C
for(int i = 0; i < k; i++)
{
C[i] = 0;
}
cout<<endl;
//遍历A中的每个元素,如果一个输入元素的值为i,就将C[i]值加1;
//遍历结束后,C[i]中保存的就是等于i的元素个数
for(int j = 1; j <= 20; j++)
{
C[A[j]] = C[A[j]] + 1;
}
// 通过加总计算确定每一个i = 1,1,...,k,有多少个元素时小于i的
cout<<"A中每个元素的个数:"<<endl;
cout<<C[0]<<" ";
for(int i = 1; i < k; i++)
{
C[i] = C[i] + C[i-1];
cout<<C[i]<<" ";
}
cout<<endl;
//把每个元素A[j]放在输出数组B中的正确位置上。
for(int j = 20; j > 0; j--)
{
B[C[A[j]]] = A[j];
C[A[j]] = C[A[j]]-1;
}
cout<<endl;
delete [] C;
}


排序结果:



首先,计数排序不是一个比较算法。其次,计数排序在运行是需要申请两个额外的空间。当A中的元素非常大且稀疏时,C中空间就会浪费,同时,如果A的规模很大时,其实不适用计数排序。但是,计数排序有一个重要的性质,就是,它是稳定的排序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: