1.计数排序思想
假设:n
个输入元素中的每一个都是在0
到k
区间内的一个整数。
思想:对每一个输入元素x
确定小于x
的元素个数。利用这一信息,就可以直接把x
放到它在输出数组中的正确的位置上。
2.计数排序实现
计数排序-伪代码:
FUNCTION Counting_Sort(A, B, k)
let C[0, .., k] be a new array /* 创建临时数组C */
for i = 0 to k /* 初始化数组C */
C[i] = 0
for j = 0 to k /* 统计值为A[j]的元素个数 */
C[A[j]] = C[A[j]] + 1
for i = 0 to k /* 统计值小于等于A[i]的元素个数 */
C[i] = C[i] + C[i - 1]
for j = A.length downto 1
B[C[A[j]]] = A[j]
C[A[j]] = C[A[j]] - 1
- 第2行创建临时数组
C
用于保存值0
到k
的元素个数。 - 第3-4行初始化临时数组
C
。 - 第5-6行循环遍历每一个输入元素,统计其个数到数组
C
中。执行完后,C[i]
中保存的是等于i
的元素个数。 - 第7-8行通过加总计算确定对每一个
i = 0, ..., k
,有多少输入元素是小于等于i
的,保存到C[i]
中。 - 第9-11行循环将每一个输入元素
A[j]
放到它在输出数组B
中正确的位置上。如果所有元素都是互异的,那么当第一次执行第10行时,对每一个A[j]
值来说,C[A[j]]
就是A[j]
在输出数组中的最终正确位置。但所有的元素并不一定都是互异的,所以我们每将一个值A[j]
放入数组B
中以后,都要将C[A[j]]
的值减1。这样,当遇到下一个值等于A[j]
的输入元素时,该元素可直接被放到输出数组中A[j]
的前一个位置上。
3. 分析
该计数排序的总时间代价为Θ(k+n)。在实际工作中,当k = O(n)时,我们一般采用计数排序,运行时间为Θ(n)。
计数排序的一个重要性质就是它是稳定的:具有相同值的元素在输出数组中的相对次序不变。也就是说,对两个相同的数来说,在输入数组中先出现的数,在输出数组中同样位于前面。通常,这种稳定性只有当进行排序的数据还附带卫星数据时才比较重要。