Skip to content

计数排序

Counting sort

对有限整数键频数计数并按前缀位置输出的线性时间非比较排序。

条目类型
算法

形式陈述

计数排序适用于每个键是区间 {0,,k} 中整数的记录。先统计每个键出现次数,再取前缀和确定各键在输出中的结束位置,最后按输入逆序稳定放置。在能以一个机器字表示键、以常数时间寻址计数数组的Word-RAM上,确定性最坏时间为 Θ(n+k),额外空间为 Θ(n+k)(可按是否保留记录调整)。它不通过元素间比较排序,因此不受比较排序 Ω(nlogn) 下界约束。若只输出键而不保留记录,可直接按计数重写。

直觉

键域小时,与其比较元素,不如用值域索引为每个可能键开桶:先统计每个键出现次数,再把计数累加成连续输出区间。它把时间从 nlogn 改为 n+k,代价是依赖有限且可寻址的键范围 k。稳定版本的前缀计数不仅告诉“有多少”,还精确给出每个键在输出中的结束位置。

计数排序的计数、前缀和与稳定输出
例子与边界

输入 [2,0,2,1] 时,频数 [1,1,2] 的前缀和会直接给出三个键各自占据的输出区间。进一步看一个包含空桶的例子:

输入 [2,5,3,0,2,3,0,3]、值域 05 时,频数为 [2,0,2,3,0,1];累加后可把每个元素从右向左放入对应位置,得到稳定排序 [0,0,2,2,3,3,3,5]

从右向左放置是为了让相同键的记录保持原顺序;若只排序键而不附带记录,则无须这一步稳定性保证。若 kn,例如键范围是 0109 而只有几百个元素,直接分配桶既浪费空间又会比比较排序更差;可压缩坐标或使用稀疏映射,但表示方式会改变复杂度,压缩本身通常还需要排序。负键可整体平移,浮点、任意实数或对象则需先提取有限整数键。计数排序以比较排序作为复杂度边界的对照,但本身不属于比较模型。

推论与应用

数组存储频数,前缀和把频数变成位置。计数排序是小整数键、直方图与离散事件聚合的基础,也是 LSD 基数排序保持稳定性的关键子过程。更一般的整数排序会在 k 太大而不能直接开桶时改用分位、打包或递归字典结构;这些算法的界依赖字长 w 和允许的字操作,不能由 Θ(n+k) 简单删去 k 得到。

参考资料
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022,Parts I–VI。
  • Donald E. Knuth, The Art of Computer Programming, Vol. 3: Sorting and Searching, 2nd ed., Addison-Wesley, 1998,Chs. 5–6。
关系图谱6 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系