计数排序
主要思想:前面的合并、快速、堆排序都是基于数据的比较,其在最坏的情况下都需要做O(nlogn)次的比较。而计数排序是对每一个元素,确定出小于元素的个数,然后根据个数将原来的数据重新的进行放置。效率与选择排序一样,但是还占用了额外的空间
计数排序的效率不高,但是对于统计来说,就比较的有用,用于统计出现的频率。这种频率的累积和在统计中被成为分布,这种的方法本身也就做分布计数
int* ComparisonCountingSort(int *CountingArray,int length)
{
int *tempArray=new int[length]();
int *S=new int[length];//最终数据存放的数组,这里不能使用清空,memset
for (int index=0;index<length;index++)//对辅助数组进行赋值
{
for (int k=index+1;k<length;k++)
{
if (*(CountingArray+k)<*(CountingArray+index))//若是比这个元素小的。则在辅助数组对应的值加1
{
*(tempArray+index)+=1;
}
else
{
*(tempArray+k)+=1;
}
}
}
for(int i=0;i<length;i++)
{
S[tempArray[i]]=*(CountingArray+i);
}
return S;
}
//假设数据是处于0-maxkey之间的数据
int * DistributionCounting(int *countingArray,int length,int maxkey)//分布统计
{
//用分布计数法,对来自于有限范围整数的一个数组进行排序
//输入:数组A,数组中的证书位于某个整数之间
//输出:A中元素构成的非降序数组S
//思想:利用一个maxkey大小的数组放置每个元素的个数。注意这个maxkey大小不一定等于length.
int *S=new int[length];
for (int i=0;i<length;i++)
{
*(S+i)=0;
}
int *temp=new int[maxkey+1];
for (int i=0;i<maxkey+1;i++)
{
*(temp+i)=0;
}
for (int i=0;i<length;i++)
{
*(temp+*(countingArray+i))=*(temp+*(countingArray+i))+1;//统计每个数字出现的次数
}
for(int j=1;j<maxkey+1;j++)
{
*(temp+j)=*(temp+j)+*(temp+j-1);//统计小于等于当前元素的个数
}
for (int k=0;k<length;k++)
{
*(S+*(temp+*(countingArray+k))-1)=*(countingArray+k);//切记这里要减去1,因为在判断的时候最低位是按照个数来算的,然而索引要减去1
*(temp+*(countingArray+k))-=1;
}
return S;
}
int main()
{
int testArray[]={6,4,10,5,7,9,3,2,8,1};//数组必须是确定的。
int *resulArray=ComparisonCountingSort(testArray,10);
cout<<"最终数据是:"<<endl;
for (int i=0;i<10;i++)
{
cout<<*(resulArray+i)<<" ";
}
cout<<endl;
cout<<"经过分布式的统计计数之后的数据是:"<<endl;
resulArray=DistributionCounting(testArray,10,10);
for (int i=0;i<10;i++)
{
cout<<*(resulArray+i)<<" ";
}
cout<<endl;
return 0;
}