【发布时间】:2018-12-21 03:04:53
【问题描述】:
我正在尝试实现快速排序,以便可以在不同的输入上分析它的运行时间。我下面的实现在预排序的输入(升序的整数)上运行得非常糟糕。
给定整数 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);
}
}
【问题讨论】:
-
你试过debugging 看看它到底在做什么吗?您可以专门尝试分析数组的相关部分(在中值调用之前和之后)和每个步骤的枢轴。
-
为什么i和j是全局变量
-
因为您使用最右边的元素作为枢轴,并且在排序列表中完成此操作时,这会导致长期错误的枢轴选择。这已详细介绍:geeksforgeeks.org/when-does-the-worst-case-of-quicksort-occur
-
你为什么将 pointers 传递给向量而不是使用引用?你可以使用
std::swap吗? -
附带说明,我不会更改中值选择中元素的顺序。这是一个副作用,方法名称肯定没有清楚地表达出来,听起来像是一个纯粹的“get”方法。
标签: c++ algorithm performance sorting quicksort