命名排序算法.是快速排序吗

Naming the sorting algorithm. Is it QuickSort?

本文关键字:快速排序 算法 排序      更新时间:2023-10-16

对于我编写的排序算法,我有两个问题:

1.当我范围填充向量[max-num, 0](最坏情况)时,我得到的结果比O(n^2)好得多。(我甚至不确定我是否还写过快速排序)。

2.当我混淆范围时,例如:我先填充未排序的向量[0, max-num/2],然后填充[max-num/2, 0],奇怪的是,它的运行速度高达900000,但紧接着就崩溃了。

template<class writeIter>
void quicksort(writeIter begin, writeIter end)
{
if (begin!= end) {
    int diff = end-begin;
    if (diff > 2) {
        writeIter pivot = ((end-begin) / 2) + begin;
        writeIter itFirst = begin;
        writeIter itSecnd = end-1;
        auto pivotVal = *pivot;
        swap(*pivot, *(end-1));
        while (itFirst < itSecnd) {
            if (*itFirst > pivotVal) {
                while (*itSecnd > pivotVal && itSecnd > itFirst) --itSecnd;
                if (itSecnd > itFirst)
                    swap(*itFirst, *itSecnd);
            }
            ++itFirst;
        }
        swap(*itSecnd, *(end-1));
        quicksort(begin, itSecnd);
        quicksort(itSecnd, end);
    }
    else if (diff  == 2)
        if (*begin > *(begin+1))
            swap(*begin, *(begin+1));
 }
}

是的,这是一种简单的快速排序。但您选择中间元素而不是最后一个元素作为轴心。

  1. 当你填充一个向量[max-num,0]时,它实际上是而不是最坏的情况。因为每次你选择中间元素作为轴心,将向量分成两部分大小几乎相同,因此时间复杂度为O(nlogn)
  2. 然而,当你填充未排序的向量[0,max num/2],然后填充[max num/2,0]时,这对你的算法来说是最坏的情况,因为你把向量分成两部分,一部分非常长,另一部分非常短。所以时间复杂度是O(n^2)

为了在几乎所有矢量上获得更好的性能,您可以:

  • 选择一个随机元素作为轴心
  • 随机挑选三个元素,然后选择第二大元素
  • 当向量的大小足够小,例如小于10时,对其应用插入排序
  • 为了处理所有元素彼此靠近的情况,可以在递归排序子向量以跳过等于pivot的元素之前做一些额外的工作