【问题标题】:Why is my quick-sort slower than merge-sort?为什么我的快速排序比合并排序慢?
【发布时间】:2021-06-19 09:47:08
【问题描述】:

这是我的实现。当我放置 10000 个大小为 1000000 的数组时,它会排序 300 秒。 我的另一种算法,合并排序执行 40 秒。 我想知道是否有一些事情会减慢我的算法。

template <typename TYP> void quick_sort(TYP *tab, int poczatek, int koniec) {
  int i = poczatek;
  int j = poczatek;
  int srodek = (poczatek + koniec) / 2;
  int piwot = tab[srodek];

  swap(tab[srodek], tab[koniec]);

  for (i = poczatek; i < koniec; i++) {
    if (tab[i] < piwot) {
      swap(tab[i], tab[j]);
      j++;
    }
  }
  swap(tab[koniec], tab[j]);

  if (poczatek < j - 1)
    quick_sort(tab, poczatek, j - 1);

  if (j + 1 < koniec)
    quick_sort(tab, j + 1, koniec);
}

【问题讨论】:

  • 你也可以分享其他算法吗?以及您如何测量代码?具体来说,您提供了哪些意见?
  • 快速排序在众所周知的条件下表现不佳。您似乎没有采取措施避免这些情况。
  • 尝试运行内置 C qsort 并查看其时间,以了解是算法遇到了退化情况,还是您的实现被破坏了。
  • 40 秒对于 1000000 个值的数组来说似乎相当慢。输入类型是什么?您是否启用了编译器优化标志?
  • qsort 不要求它实际使用快速排序算法。

标签: c++ performance sorting merge


【解决方案1】:

快速排序的平均运行时间为O(n log(n)),但如果枢轴选择不当,则最坏情况下的复杂度为O(n^2)。关于您的输入数组,您选择的枢轴可能非常糟糕。为防止这种情况,您可以实现 Introsort。此外,您可以使用更好的方法来选择枢轴:例如median-of-three 规则。

此外,快速排序对于小型数组来说很慢。例如,对于小于 15 的数组,您可以使用 insertion-sort 显着提高其性能。最后的递归调用会更快,从而导致整体执行速度更快。

最后,您的快速排序使用 Lomuto 分区方案,这可能不是最有效的。您可以尝试使用 Hoare 的分区方案

【讨论】:

    猜你喜欢
    • 2015-06-25
    • 2021-06-06
    • 2010-10-04
    • 2017-03-18
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-14
    • 2011-06-02
    相关资源
    最近更新 更多