给定预分类的输入后,为什么我的quicksort实施缓慢?

时间:2018-07-12 19:30:04

标签: c++ algorithm performance sorting quicksort

我正在尝试实现quicksort,以便可以在不同的输入上分析它的运行时。我在下面的实现在预分类输入(整数按升序)上的运行非常差。

给出整数1-5000,这是我排序的运行时:

  • 随机排序的输入:0.052秒
  • 降序输入:0.065秒
  • 升序输入:0.209秒

给出整数1-50000,这是我排序的运行时:

  • 随机排序的输入:0.585秒
  • 降序输入:1.598秒
  • 升序输入:6.540秒

我不确定是什么原因导致预排序输入上的长时间运行。

int median(vector<int> *input, int left, int right) {
    int mid = (right + left) / 2;
    int temp;

    // This method also orders the selected left, mid, and right values
    if ((*input)[mid] < (*input)[left]) {
        temp = (*input)[mid];
        (*input)[mid] = (*input)[left];
        (*input)[left] = temp;
    }
    if ((*input)[right] < (*input)[left]) {
        temp = (*input)[left];
        (*input)[left] = (*input)[right];
        (*input)[right] = temp;
    }
    if ((*input)[mid] < (*input)[right]) {
        temp = (*input)[mid];
        (*input)[mid] = (*input)[right];
        (*input)[right] = temp;
    }

    temp = (*input)[mid];
    (*input)[mid] = (*input)[right-1];
    (*input)[right-1] = temp;

    return (*input)[right-1];
}

void quickSort2(vector<int> *input, int left, int right) {
    if (left < right) {
        // Get pivot (median of 3)
        int pivot = median(input, left, right);
        int temp;

        int i = left, j = right - 1;
        for (; ; ) {
            while ((*input)[++i] < pivot) {}
            while (j > 0 && (*input)[--j] > pivot) {}
            if (i < j) {
                temp = (*input)[i];
                (*input)[i] = (*input)[j];
                (*input)[j] = temp;
            } else {
                break;
            }
        }

        temp = (*input)[i];
        (*input)[i] = (*input)[right - 1];
        (*input)[right - 1] = temp;

        quickSort(input, left, i - 1);
        quickSort(input, i + 1, right);
    }
}

1 个答案:

答案 0 :(得分:3)

因为您使用最右边的元素作为枢轴,并且在排序列表中完成此操作后,这将导致长期错误地选择枢轴。这已经详细介绍了:geeksforgeeks.org/when-does-the-worst-case-of-quicksort-occur

尝试更改您的第三个条件:

if ((*input)[mid] < (*input)[right]) {

if ((*input)[right] < (*input)[mid]) {

否则,交换会将最右边(最大)的元素放入[mid],然后(最终)将其作为输出返回。

为清楚起见而编辑