前两篇介绍的梳排序和gnome排序,都是属于比较排序算法里面的交换排序方法。而计数排序是一种非比较排序算法,其C代码如下:
计数排序的时间复杂度是O(n + k),其中k代表该数组元素的取值范围。当数组中的所有元素均相差不大,最多互为线性关系时,计数排序的时间复杂度可以化为O(n),在此情况下,计数排序的速度快于任何比较排序算法。
但是,计数排序也很有局限性。首先,只能排序整数,不能对浮点数和字符串进行排序;其次,需要额外的存储空间,该算法需要为每一个最小值到最小值加k之间的数,不管这个数在原数组中存在还是不存在,都要统计它在原数组中出现的次数,所以,当k比较大时,可能也是一笔不容忽视的开销。
本文的比特计数排序,正是为解决额外的存储空间问题而提出的。(注,写本文时并没有参考其它博客、资料或文献,不清楚该算法是否有更合适的名字,所以就按个人的理解命名为比特计数排序)
在不少情况下,我们只关心需要排序的键值,作为一个主键,有没有出现,不关心它出现了几次。这时候,如果使用一个整型变量来表示一个数组元素有没有出现,就有点浪费了。事实上,这仅仅需要一个比特,就可以做到:用1代表约定的元素有出现,0代表约定的元素没有出现。那么,一个无符号整数,在32位操作系统下,就可以对应普通计数排序里的32个count数组的元素。也就是说,比特计数排序仅需要普通计数排序所必须的额外存储空间的1/32,即可工作。
该算法如下:
算法的前半部分,比特计数排序与普通计数排序是基本一样的,不外乎找出最大和最小的元素,分配count数组的空间并对其进行初始化,等等。后半部分,比特计数排序遍历count数组的次数比普通计数排序少,但是每次遍历的逻辑处理相对复杂,需要对每个位进行统计。实验证明,比特计数排序的效率与普通计数排序差不多。在我的电脑上,分别对一个4K大小的整型数组执行10000次洗牌和排序,多次执行,两者的运行时间都是4秒多。
此外,我曾经尝试使用移位和位运算代替算法中的整除和取模运算,以为能够大大提升执行速度,但是,事与愿违,这样修改后并没有带来任何性能上的提升。看来,现在的编译器早就对此进行了一定的优化,不必程序员操心了。
无可否认,比特计数排序同样有很大局限性:第一,还是只能对整数排序;第二,还是需要不少的额外存储空间,尽管占用的空间已经大大减少;第三,会去掉重复的元素。不过,寸有所长,尺有所短,在我看来,比特计数排序恰恰能满足那些要求去掉重复键值,或者键值已经是唯一值的场合。
分享到:
相关推荐
伪代码和算法介绍在此:http://www.algorithmist.com/index.php/Counting_sort,本程序是 根据这个伪代码编写的源代码
CountingSort为AlgorithmMan中的计数排序演示工具(这是可执行文件;需要.net 4.0支持;非源代码)。 原文:C#算法设计排序篇之08-计数排序(附带动画演示程序) 链接:...
var countingSort = require ( './countingSort.js' ) ; // Construct input [0, 5], therefore an array of size 6 is needed // for the temporary storage space. var input = [ 2 , 5 , 3 , 0 , 2 , 3 , 0 , 3 ...
经典的排序算法C#源码,包括: 经典排序算法 - 快速排序Quick sort 经典排序算法 - 桶排序Bucket sort 经典排序算法 - 插入排序Insertion sort 经典排序算法 - 基数排序...经典排序算法 - 计数排序Counting sort
countingSort 方法实现了计数排序算法。首先,我们遍历一遍原数组,找出其中的最大值,以确定计数数组的大小。然后,创建计数数组 count,并将每个元素的出现次数记录在计数数组中。接下来,根据计数数组中的元素...
计数排序(Counting Sort) 循环排序(Cycle Sort) 双重排序(Double Sort) 荷兰国旗排序(Dutch National Flag Sort) 交换排序(Exchange Sort) 外部排序(External Sort) 侏儒排序(Gnome Sort) 堆排序...
排序算法 排序算法_基于C语言实现的排序算法之CountingSort实现
JavaScript计数排序算法计数排序算法计数排序(Counting sort)是一种稳定的线性时间排序算法。计数排序使用一个额外的数组,数组的下标对应待排序
计数排序并行openmp Esterepositórioabriga实施工具会按顺序对序数进行排序。 Esses algoritmos foram desenvolvidos no Programme da Disciplina deProgramaçãoParalela e Multicore do curso deCiê...
计数排序(Counting sort)是一种稳定的排序算法。计数排序使用一个额外的数组Count_arr,其中第i个元素是待排序数组Arr中值等于i的元素的个数。然后根据数组Count_arr来将Arr中的元素排到正确的位置。分为四个步骤:1...
计数排序(Counting Sort) 基数排序(Radix Sort) 桶排序(Bucket Sort) 深度优先搜索(Depth-First Search, DFS) 广度优先搜索(Breadth-First Search, BFS) 二分查找(Binary Search) 线性查找(Linear ...
def _counting_sort(A, B, k): “””计数排序,伪码如下: COUNTING-SORT(A, B, k) 1 for i ← 0 to k // 初始化存储区的值 2 do C[i] ← 0 3 for j ← 1 to length[A] // 为各值计数 4 do C[A[j]] ← C...
计数排序计数排序是一种基于特定范围内的键的排序技术。 它通过计算具有不同键值的对象数量来工作(类似于哈希)。
java十大排序算法实现 1. 冒泡排序(Bubble Sort) 2. 选择排序(Selection Sort) ...7. 计数排序(Counting Sort) 8. 桶排序(Bucket Sort) 9. 基数排序(Radix Sort) 10. 希尔排序(Shell Sort)
yolov5 deepsort 行人 车辆 跟踪 检测 计数 实现了 出/入 分别计数。 默认是 南/北 方向检测,若要检测不同位置和方向,可在 main.py 文件第13行和21行,修改2个polygon的点。 默认检测类别:行人、自行车、小汽车、...
数据结构与算法-Python语言案例实现十大经典排序算法一、 ... 计数排序(Counting Sort)9. 桶排序(Bucket Sort)10. 基数排序(Radix Sort)三、算法总结 十大经典排序算法 一、 引言 授人以鱼不如授人以渔~ 实践是检
leetcode 和 ...计数排序 counting sort 基数排序 radix sort 桶排序bucket sort 堆排序 heap_sort 二分查找 69 744 540 278 852[Easy] 贪心法 455 [Medium]435 [Medium]452 [Medium]406 121 122 605
To reflect that, and to make the Counting Practices Manual (CPM) even more attractive as a reference manual, the Counting Practices Committee (CPC) decided to restructure CPM 4.2 into four parts: ...
方法 天真地检查每一位 每个字节的查询表 比较 我测试了三种不同的位计数策略:每个位的朴素计数,每个字节的查找表以及SWAR位计数。... 事实证明,这比未排序的数组处理排序的数组要快得多。 进行了一些谷歌
利用差分盒计数法计算图像分维数,利用matlab语言编写