【问题标题】:Does comparison really take O(1) time? and if not... why do we use comparison sorts?比较真的需要 O(1) 时间吗?如果不是……我们为什么要使用比较排序?
【发布时间】:2014-03-13 09:08:35
【问题描述】:

考虑两个 k 位数(二进制表示):

$$A = A_1 A_2 A_3 A_4 ... A_k $$

$$B = B_1 B_2 B_3 B_4 ... B_k $$

为了比较,我们从左到右扫描寻找 0 的出现,并检查相反的数字,如果该数字也是 0(对于两个数字),请注意如果找到这样的情况,那么源0 的来源小于 1 的来源。但如果数字是:

111111111111
111111111110

显然,这将需要扫描整个数字,如果我们事先没有被告知数字并简单地给出它们,那么:

比较采取$O(k)$ 时间。

因此,当我们查看诸如高性能快速排序之类的排序方法的代码时:

HPQuicksort(list): T(n)
  check if list is sorted: if so return list
  compute median: O(n) time (or technically: O(nk))

  Create empty list $L_1$, $L_2$, and $L_3$ O(1) time

  Scan through list  O(n)

  if element is less place into $L_1$ O(k)

  if element is more place into $L_2$ O(k)

  if element is equal place into $L_3$ O(k)

  return concatenation of HP sorted $L_1$, $L_3$, $L_2$  2 T(n/2)

因此:T(n) = O(n) + O(nk) + 2*T(n/2) ---> T(n) = O(nklog(n))

这意味着快速排序比基数排序慢。

那我们为什么还要使用它呢?

【问题讨论】:

  • 我看到 mathjax 在这里不起作用。你建议我如何格式化?
  • 代码格式。它不像 MathJax 那样功能丰富,因为它主要是对所有内容进行等宽处理,但它就是我们所拥有的。
  • 对不起,什么?比较是在硅中实现的。它需要一个周期或其他东西。你能澄清一下你在说什么吗?如果您正在对具有任意长度位的 BigInt 数据结构的实例进行排序,那当然——我认为这是一件非常罕见的事情。如果您正在对整数(32/64 位)进行排序:1)无论如何它都是 O(1),因为 k 是有上限的。 2)它甚至不是 O(n) 达到上限,因为它是立即完成的。
  • 对两个整数进行排序需要调用它们的位比较。如果整数不是固定大小的,则不是恒定时间操作。
  • 即使如此,如果整数是固定大小的,显然基数排序比快速排序更快。

标签: sorting complexity-theory time-complexity quicksort radix-sort


【解决方案1】:

这里似乎有两个独立的问题:

  1. 为什么我们声称在分析排序算法时比较需要 O(1) 时间,而实际上可能不需要?

  2. 为什么我们要对大整数使用快速排序而不是基数排序?

对于 (1),通常,排序算法的运行时分析是根据进行的比较次数而不是执行的操作总数来衡量的。例如,著名的排序下界给出了比较次数的下限,快速排序、堆排序、选择排序等的分析都是通过计算比较来进行的。出于几个原因,这很有用。首先,通常,排序算法将通过给定一个数组和一些用于比较它们的比较函数来实现(例如,C 的qsort 或Java 的Arrays.sort)。从排序算法的角度来看,这是一个黑盒子。因此,通过尽量减少对黑盒的调用次数来分析算法是有意义的。其次,如果我们确实通过计数比较来分析排序算法,那么通过将比较的数量乘以比较的成本就很容易确定整体运行时间。例如,您正确地确定使用快速排序对 n 个 k 位整数进行排序将花费预期时间 O(kn log n),因为您只需将比较次数乘以比较的成本即可。

对于您的第二个问题 - 为什么我们要对大整数使用快速排序而不是基数排序? - 通常,由于您指出的特定原因,您实际上会在这种情况下使用基数排序,而不是快速排序。 Quicksort 是一种出色的排序算法,用于对可以相互比较的对象进行排序并且具有出色的性能,但基数排序在大型字符串或整数的大型数组上经常优于它。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 2018-03-30
    • 2011-09-23
    相关资源
    最近更新 更多