由于所有比较排序算法至少花费n lg n时间,为什么我们需要使用类似quicksort的东西,当我们可以将快速排序列表中的项目表示为位并使用基线的基数排序?
答案 0 :(得分:2)
Radix排序往往表现出较差的缓存局部性,例如参见this paper,用于分析缓存影响下的不同排序算法(跳过结论,讨论基数排序的缓存局部性与quicksort相比较差)归并排序)。 Quicksort和mergesort对数据进行分区,使得在几次迭代之后,分区将适合几个缓存行,而基数排序会保持数据的混乱。另外,基数排序要么需要为其桶使用链接数据结构(缓存性能较差),要么需要使用过大的数组(浪费内存)。
此外,根据基数排序的基数大小,其常数因子可能大于quicksort的/ mergesort的对数因子。在极端情况下,在64位整数上使用2的基数,基数排序具有64的常数因子(每位一次通过),而快速排序/合并输出的对数因子很大(因为这意味着你正在排序2 ^ 64个元素)
答案 1 :(得分:1)
使用SIMD内核对short数组进行排序的mergesort的现代实现可以非常非常快。 This paper by some folks at Intel描述了一个这样的实现。这里的主要优点是SIMD内核可以在每个时钟周期进行多次比较和交换,获得并利用有关每个时钟周期要排序的阵列的几位信息。
Quicksort需要测试,存储以及每次迭代时两个指针之一的增量,这形成了一个巨大的依赖链。这并不好,因为这意味着你每隔几个时钟周期就获得一些关于阵列的信息。
Radix排序与Quicksort具有相同的问题(每个pass都是一个巨大的依赖链,其中一个指针来自一个较大的,均匀分布的集合的访问和增量)。但是,在均匀分布的输入上,使用五位或六位密钥正确实现的MSD基数排序可以在输入中一次完成,Quicksort将需要五到六次传递才能完成。我最近没有计算这些东西,但是一个好的MSD基数排序可能仍然是对int
或long long
s的大型数组进行排序的最佳方法。
如果您的输入分布不均,并且与输入中的键数相比,可能键的范围很大,那么关于基数排序的这些内容都不会让您在晚上保持温暖。