【问题标题】:Why bother with comparison sorts?为什么要使用比较排序?
【发布时间】:2012-10-22 13:49:33
【问题描述】:

Timsort、Quicksort 和 Mergesort 等算法在“现实世界”排序方法中占主导地位。这些比较排序的案例非常实用——它们已被证明是各种环境中性能最高、最稳定、用途最广泛的排序算法。

但是,我们在计算机上排序的几乎所有内容似乎都是可数/部分排序的。数字、字符、字符串,甚至函数都适用于一些有意义的非比较排序方法。这里的一个候选者是基数排序。一般来说,它会比 O(n*log(n)) 表现得更快,在许多复杂度为 O(K*n) -- K 的情况下,大大超过了 n * log(n) 的理论比较排序限制是表示特定项目所需的位数。

什么给了?

【问题讨论】:

  • +1 我也一直想知道为什么似乎没有(标准或有效标准的)库提供类似聪明的基数排序变体的东西。但请注意:(1)“表示特定项目所需的位数”是针对 n 个不同项目的顺序log n——这并不是基数排序可以击败基于比较的排序的真正原因。 (2) Introsort 并不是唯一被广泛使用的排序算法,至少有两个流行的标准库使用了 Timsort。
  • 顺便说一下,Quicksort 不稳定。
  • 快速排序不一定是稳定的,但这是一个实现细节。快速排序可以以稳定的方式运行。
  • “可以以稳定的方式表现”是什么意思?您将如何编写稳定的快速排序?
  • @DanielFischer:您可以添加 作为 tie-breaker 基于指针值的最终比较。 (这在 C 中是有效的,因为两个指针都应该指向同一个数组对象的元素。但这当然假设一个比较函数或等效函数)更新:我混淆了快速排序和 qsort()。

标签: algorithm sorting quicksort radix-sort


【解决方案1】:

基数排序的速度取决于键的长度。如果你有像字符串这样的长键,基数排序可能会很慢。

此外,对于仅对少数项目进行排序的初始化成本可能会比实际排序高出一个数量级。

例如,如果您使用 8 位基数对 32 位整数进行排序,则需要初始化 256 个存储桶列表的至少 4 倍 - 如果您只有 20 个左右的项目来排序,那么 80 次交换会慢得多比快速排序需要大约 200 次比较/交换。

如果您对任何更长的内容(例如字符串)进行排序,则最长字符串的每个字符都有一个存储桶初始化 - 这可能会更糟。

【讨论】:

  • 这些基本问题是基数排序还是简单实现?我倾向于后者(这会让你的观点变得毫无意义),但我不是专家。
  • 关于初始化的大部分要点都可以通过一个体面的实现轻松解决(通过对相当小的尺寸进行一些其他类型的排序)。但是长键的问题是基数排序的一个非常基本的问题(想想你所有的字符串键都有相同的长前缀)。
  • @KeithRandall 长前缀对于比较来说同样是个问题。
  • “基数排序的速度取决于键的长度。”...而比较排序的速度不是吗?
【解决方案2】:

基数排序在使用整数键对对象进行排序时很有用,从实际性能的角度来看,它在很大程度上取决于键的长度。对于对任意对象进行排序的一般情况,这还不够 - 因此需要基于比较的排序。

【讨论】:

  • 你能举个例子吗?在许多情况下,美国国旗排序在字符串的字典顺序方面比快速排序更快。
【解决方案3】:

比较排序基于一个非常好的抽象:您所需要的只是一种比较两个元素的方法。然后,根据您的语言,使用模板 (c++)、接口 (java)、类型类 (haskell)、函数对象 (javascript) 等。您可以对可以容纳任意类型的容器进行排序,您唯一需要的就是实现比较.

您将如何为任意类型实现基数排序? :)

【讨论】:

  • 你当然不能,但我认为在没有预先存在的排序表示(自然、字典顺序等)的情况下对任意类型进行排序是有道理的,这种情况几乎不会立即发生。
  • @ZephyrPellerin 我不想为我使用的每个对象编写一个类似于基数排序的算法。基于比较的算法很好,因为实现不依赖于要排序的对象;所以你可以编写一个通用的快速排序函数(或使用你的语言库中的一个),并用一个比较器来提供它以用于排序。这就是抽象的目的。
  • @Haile 如果我弄错了,请纠正我,我从未实现过基数排序。但是 AFAIK 只需要从要排序的项目到键(整数)的函数,然后可以通过在键上运行它来重用基数排序。
  • 更像是一组键,作为大多数语言中的纯整数显然无法容纳所有可能的值。
  • 您能否提供一个示例,在该示例中您实现了一个比较函数,而没有使用可以很容易地提供给基数排序算法的属性或函数?即object.age,object.size,甚至object.name等。
猜你喜欢
  • 2014-03-13
  • 2015-06-28
  • 2013-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多