何时使用非比较排序而不是比较排序

时间:2013-01-20 04:40:25

标签: algorithm sorting

在课堂上,为了避免所有基于比较的排序的omega(nlogn)的下限,我们学习了一堆新的非比较排序。但对我来说有点不清楚的是专业人士和什么时候使用哪一类排序算法。

不能调整任何数据集,以便可以使用非比较排序算法(基数,桶,键索引)?如果是这样,比较的重点是什么呢?

很抱歉这是一个基本的问题,但我真的找不到任何在线内容。

4 个答案:

答案 0 :(得分:2)

并非每一项都可以调整,以便以有效的方式在非比较分类中使用。例如,对任意精度数进行排序需要多次在桶内运行循环,从而导致性能下降。

世界上基数种类的问题是它们必须检查每个被分类项目的每个元素。另一方面,基于比较的排序可以跳过相当数量的子元素(数字,字符等)。例如,当比较函数检查两个字符串时,它会在第一个差异处停止,跳过两个字符串的尾部字符串。另一方面,存储桶排序必须检查每个字符串 * 中的所有字符。

一般来说,追求最佳渐近复杂度并不总是一个好策略:使用更复杂的算法得到的N的值通常太高而不能使更复杂的算法变得实用。例如,quicksort的时间复杂度非常差,但平均而言,由于其非常低的开销,它击败了大多数其他算法,使其成为大多数实际情况下的不错选择。

<小时/> * 在实践中,桶排序的实现避免了需要通过在桶中的项目数量切换到基于比较的排序来查看所有子元素(数字,字符等)降到某个阈值以下。这种混合方法优于基于比较的简单排序和普通桶排序。

答案 1 :(得分:1)

非比较排序的问题在于它们的复杂性通常取决于除输入大小之外的其他参数。例如,基数排序具有O(kn)复杂度,其中k是元素中最高的位数 - 问题是,k如何与n相关。如果k与n大约相同,则算法变为O(n ^ 2)。

答案 2 :(得分:1)

基于非比较的排序算法对输入进行假设。输入的所有元素都需要落在恒定长度的范围内,以确保线性时间复杂度。另一方面,基于比较的排序算法不对输入做出假设,并且能够解决任何情况。基于非比较的排序算法通常以额外的内存成本和缺乏输入的一般性为代价。

答案 3 :(得分:1)

当你懒得编写非基于比较的排序时,你可以使用基于比较的排序。

基于比较的排序本质上较慢;他们需要在输入元素上多次调用一个比较器,每次调用都会给基于比较的排序提供一点信息。正确的基于比较的排序必须平均累积log_2(n!)〜= n log(n)位的有关其输入的信息。

现在,所有数据都在机器中有一个表示。您可以根据您的特定类型的数据,它所具有的表示以及您用于排序的机器来定制排序算法,如果您知道自己在做什么,那么您通常可以在任何基于比较的基础上打败这些数据。排序算法。

然而,性能并非一切,并且有些情况(实际上我见过的大多数情况)最高性能的解决方案并不是正确的解决方案。良好的基于​​比较的排序可以采用黑盒比较器,并且对输入进行小的常数n log(n)比较。这几乎适用于所有应用程序。

编辑:以上内容仅适用于内部排序,其中有足够的RAM来存储整个输入。外部排序(例如,溢出到磁盘)通常应该通过一次读取大约半个RAM数据,使用非基于比较的排序,并将排序结果写出来来完成。一直小心地将输入和输出重叠排序。最后,你做了一个(基于比较的)n路合并。