【问题标题】:Sorted array except for first K and last K elements除前 K 和后 K 元素外的已排序数组
【发布时间】:2019-01-07 11:25:24
【问题描述】:

已知大小为 n 的数组 A 已排序,但前 k 个元素和后 k 个元素除外,其中 k 是常数。以下哪种算法最适合对数组进行排序?

 A) Quicksort
 B) Bubble sort
 C) Selection Sort
 D) Insertion Sort

给出的答案是 D。

无法理解这是如何工作的,如果还给出了合并排序,答案会是什么?

【问题讨论】:

  • 我想有一些假设 k 明显小于 n?否则你可以创建k = n/2 并且整个数组将是未排序的......Kk 也是一样的吗?
  • 是的 K 和 k 在这里是一样的。现已更正。
  • 这就是它令人困惑的原因......我也有同样的疑问。
  • 也许应该有一些限制才能使插入排序成为正确答案。
  • 关于您的“奖励”问题:是的,我认为合并排序 是最快的,O(2klogk + n) (=O(n) for const.k ) 用于对两个未排序的段进行合并排序,然后合并三个部分。

标签: algorithm sorting


【解决方案1】:

让我们看看算法的复杂性:

A) 快速排序:会采用更坏的情况 O(n²) 平均 O(n log n)
B) 冒泡排序:需要 O(n²)
C) 选择排序:需要 O(n²)
D) 插入排序:如果 k 是常数 = O(n)

,将采用 O(k* n)

所以D的表现最好。 (对于每个 k 个元素:O(log n) 找到要插入的位置 + O(n) 插入)

但由于已知 Quicksort 具有较小的 konstant faktor 并且平均为 O(n log n),因此“较大”的 k 值很可能更快。


额外:

E) 合并排序:需要 2 * O(k log k) + O(n)

  • 对前面的k个元素进行排序O(k log k)
  • 对最后的k个元素进行排序O(k log k)
  • 合并3个列表O(n)

总之,常数 k O(n) 因此基于与插入排序相同的复杂性。

但是如果你看它的 k 不是常数:
归并排序: O(k log k) + O(n)
插入排序: O(k* n)

所以插入排序会更快。

反对归并排序的论据:
一般来说,合并排序不是就地(插入排序是),因此您需要额外的空间或非常聪明的实现变体,以便设法在不增加复杂性的情况下就地完成。

【讨论】:

  • 插入排序怎么会有O(k*logn)的时间复杂度?
  • @ashwani yadav:你说得对,我认为找到插入位置只需要 O(log n)。根据您的数据结构,ins 插入成本很高,
  • 你的回答现在看起来很令人满意。
  • 在我的系统上,Intel 3770K 3.5 ghz,Windows 7 Pro 64 位,Visual Studio Desktop Express 2015,快速排序仅比标准合并排序快 15%。在 64 位模式下,有 16 个寄存器,其中 8 个用作指向当前运行和运行结束的指针,4 路自底向上合并排序与快速排序花费的时间大致相同,但如前所述,它需要 O(n) 空间。如果快速排序包含在递归太深时放入堆排序的代码(介绍排序),它仅比标准的 2 路合并排序快 10%,(并且比 64 位模式下的 4 路合并排序慢)。
  • 有一种比我之前链接的块合并排序更简单的就地合并排序,但它不稳定,速度较慢,而且它是递归和迭代的组合。第一季度和后半部分被排序(递归),然后合并到第二季度,将元素交换到第一季度进行合并,第一季度未排序。然后将第一个 1/8 排序并与最后一个 6/8 合并到第二个 1/8 中,使第一个 1/8 未排序。重复直到 2 个元素留在左侧,使用插入类型排序将这 2 个元素放置到位。我还没有找到这方面的在线示例。
【解决方案2】:

由于第一个 K 和最后一个 K 元素的数量是恒定的,因此计算它们的复杂度确实没有意义,因为它是恒定的。

比较以上所有给定的算法及其复杂性:

A) 快速排序:最坏情况 O(n²) 平均 O(n log n)

B) 冒泡排序:O(n²)

C) 选择排序:O(n²)

D) 插入排序:O(k* n) if k=constant = O(n)

如果反转计数是O(n),那么插入排序的时间复杂度是O(n)。在最坏的情况下,可能有 n(n-1)/2 次反转。最坏的情况发生在数组以相反的顺序排序时。所以插入排序的最坏情况时间复杂度是O(n2).*

因此,快速排序通常是最好的,但 对于小型列表插入排序有 一个优势

对于较小的 n,插入排序更快,因为快速排序具有来自递归函数调用的额外开销。插入排序也是 比快速排序更稳定,需要更少的内存。

Why is Insertion sort better than Quick sort for small list of elements?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 2011-06-27
    • 2016-02-05
    • 1970-01-01
    相关资源
    最近更新 更多