【算法】计数排序以及其java实现

本文介绍了一种名为计数排序的算法,其特点是通过空间换取时间效率,实现O(n)的时间复杂度。文章详细解释了计数排序的工作原理,并提供了一个Java实现的例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前几周算法课看算法导论看到一个排序叫计数排序,据说是一个很骚的东西,其时间复杂度为O(n)。要知道很骚的快速排序其平均时间复杂度也是O(nlgn)。看完了算法的推导过程才发现,原来只是一个空间换时间的策略。

首先,它需要我们准备三个数组,需要排序的数组A,排序后的数组B,二者同样大小。然后中间数组C,C的大小为A中最大值+1.(这个就很坑,比如我A[2] = {1,9999}那么它就会默认建立的C数组长度为10000。然而用别的排序根本用不到这么大的空间。没办法,谁让其的策略就是空间换时间呢) 然后C数组的下标代表A数组中的值,C数组对应下标的值代表下标值在A数组中出现的次数。如下图所示例子:

别看这里的C长度为4,万一A中有0呢?)

然后对C中的每个值变化为其之前所有值与本身值之和,表示A中小于等于自己的一共有多少个数。


然后,从末尾遍历A数组,找寻A数组对应的值作为下标在C数组中对应的值。然后该值就是A数组中值在B数组中值的位置:


B数组更新完后,C数组对应的位置值-1.代表剩下的A数组中小于等于该值的个数。

依次遍历一遍,就将A数组中所有的值放到了B数组中对应的位置中。

总的说来,虽然其看起来时间复杂度是O(n),但是其背后的代价是蛮大的。所以只在巨大样本的排序中会比其他排序快。并且尽量控制A数组中最大值和A数组长度的比例,不然弄一个巨长的数组C但是其变化寥寥,就比较浪费空间了。

下面是java实现的源代码。由于经常刷leetcode,得了一种不把多余的全部删掉就会死的病。所以没有注释,代码也比较紧凑,见谅。

    

public int[] JishuSort(int a[])
	{
		int cnum =0;
		for(int i = 0 ; i<a.length;i++){
			if(cnum<a[i])
				cnum = a[i];
		}			
		int[] c = new int[cnum+1];
		int[] b = new int[a.length];
		for(int i =0;i<c.length;i++)
			c[i]=0;
		for(int i = 0;i<a.length;i++)
			c[a[i]]+=1;
		for(int i =1;i<c.length;i++)
			c[i]+=c[i-1];
		for(int i = a.length-1;i>=0;i--){
			b[c[a[i]]-1]=a[i];
			c[a[i]]-=1;
		}
		return b;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值