hello同学们,又来到了涨知识的时间,都准备好小本本了吗,要开始学习喽。
学了这么多排序算法,相信同学们已经知道排序可以通过比较实现,也可以通过不比较实现了吧。
比较排序是通过比较来确定两个元素中哪个应该放在序列前面。它的算法理论的算法复杂度下限为:O(nlgn),也就是说比较排序的时间复杂度不可能比O(nlgn)更小了。
而非比较排序(如计数排序、桶排序),则可以突破O(nlgn)的时间下限。但同学们要注意,非比较排序算法的使用都是有条件限制
例如:我们今天要学习的——计数排序,对数据范围过大的元素进行排序需要耗费大量的内存和时间,但对数据范围较小的大量数据排序,计数排序却可以发挥奇妙的作用。
那接下来小软来给大家介绍一下什么是计数排序:
计数排序是一个非基于比较的排序算法,它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围,n是待排序元素的个数),快于任何比较排序算法。
计算排序算法思想:对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,我们就可以将x直接存放到最终的输出序列的正确位置上。
例如,如果输入序列中只有17个元素的值小于x的值,则x可以直接存放在输出序列的第18个位置上。当然,如果有多个元素具有相同的值时,我们不能将这些元素放在输出序列的同一个位置上,有重复时需要特殊处理(保证稳定性),需要在最后反向填充目标数组,并将每个数字的统计减去1。
计数排序算法的具体步骤:
1.找出待排序的数组中最大和最小的元素
2.统计数组中每个值为i的元素出现的次数,存入数组C的第i项,即扫描序列A,以A中每个元素的值为索引,将C中对应位置的次数统计加1,C[i]为A中i出现的次数。
3.对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)以确定值为i的元素在数组中出现的位置。
4.反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
假定输入是个数组A[1…n], length[A]=n。另外还需要一个存放排序结果的数组B[1…n],以及提供临时存储区的C[0…k](k是所有元素中最大的一个)例如:
假设数字范围在 0 到 9. A[]={0, 4, 1,2, 7,1, 5, 2,7,9}
①使用一个数组c记录每个数组出现的次数
数组索引(下标): 0 1 2 3 4 5 6 7 8 9
数组c: 1 2 2 0 1 1 0 2 0 1
②累加所有计数(从C中的第一个元素开始,每一项和前一项相加)
数组索引(下标): 0 1 2 3 4 5 6 7 8 9
数组c: 1 3 5 5 6 7 7 9 9 10
更改过的计数数组就表示每个元素在输出数组中的位置
③反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
例如:数组0, 4, 1, 2, 7, 5, 2,7,9
0的位置是1,则把0放在输出数组的第一个位置,并将计数减一。1出现的位置是3,就将3放在输出数组的第3个位置,并将计数减一,下一个1出现的时候就放在第2个位置了.(方向可以保持稳定)
具体代码实现如下:
计数排序的时间复杂度: O(n+k)与空间复杂度: O(n+k)
以上就是小软今天带来的计数排序的全部内容,大家要认真学哦,我们下期见吧!
部分图片来源于网络
责任编辑:付子腾