算法导论 — 8.2 计数排序
笔记
假设输入的个元素中的每一个都是在 ~ 内的一个整数。表示了输入元素所处的范围。一般在远小于时,可以采用计数排序算法。
计数排序的基本思想是:对每一个输入元素,确定小于的元素个数。利用这一信息,可以直接把放到正确的位置。例如,如果有个元素小于,则x就应该放在第个位置上。
以下为计数排序的伪代码。假设输入数组为,输出数组为,另外还有一个数组提供临时存储空间。
下图给出了一个例子,输入数组为。
在计数排序的伪代码中,第 ~ 行的for循环所花时间为,第 ~ 行的for循环所花时间为,第 ~ 行的for循环所花时间为,第 ~ 行的for循环所花时间为。这样,计数排序总的时间代价为。在实际应用中,一般在时才会应用计数排序,此时计数排序的运行时间为。
在8.1节,我们得到结论,比较排序的运行时间的下界为。然而计数排序的运行时间是优于的,因为它并不是一个比较排序算法。
计数排序还是一个稳定排序算法,这一玄机在于伪代码的第行,从后向前遍历输入数组。假如在存在一组数值相同的元素,位置靠后的元素先取出,它在输出数组中的位置也相对靠后;而位置靠前的元素后取出,它在输出数组中的位置也相对靠前。
练习
8.2-1 参照图8-2的方法,说明在数组上的操作过程。
解
8.2-2 试证明是稳定的。
略
8.2-3 假设我们在的第10行循环的开始部分,将代码改写为:
试证明该算法仍然是正确的。它还稳定吗?
略
8.2-4 设计一个算法,它能够对于任何给定的介于到之间的个整数先进行预处理,然后在时间内回答输入的个整数中有多少个落在区间内。你设计的算法的预处理时间应为。
解
以下直接给出伪代码。
本节相关代码链接:
https://github.com/yangtzhou2012/Introduction_to_Algorithms_3rd/tree/master/Chapter08/Section_8.2