算法--计数排序与统计计数排序

计数排序

主要思想:前面的合并、快速、堆排序都是基于数据的比较,其在最坏的情况下都需要做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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值