我已经用C ++实现了Quicksort算法的几种变体,但是它们都有一个很大的缺陷。他们无法在合理的时间内对10万个整数的数据集进行排序。有时,包含10 000个整数的数据集也会失败,但失败的频率要低得多。最初,我怀疑我选择的枢轴是造成此问题的原因,但是即使随机选择了枢轴,该算法也无法在合理的时间内执行。有人可以帮助我确定Quicksort实施效果不佳的原因吗?
下面是我使用固定枢轴的Quicksort实现。
void quicksort(std::vector<int> &list, int left, int right)
{
if (left >= right)
return;
int pivot = list[left + (right - left) / 2];
int oldPivot = partition(list, pivot, left, right);
quicksort(list, left, oldPivot - 1);
quicksort(list, oldPivot + 1, right);
}
// Hoare Partitioning Scheme
int partition(std::vector<int> &list, int pivot, int left, int right)
{
while (true)
{
while (list[left] < pivot)
left++;
while (list[right] > pivot)
right--;
// Stop when the pivot is reached.
if (left >= right)
return left;
std::swap(list[left], list[right]);
}
}
要测试我的Quicksort算法是否有向量100000无序整数,我使用以下代码:
std::vector<int> randomizeIntVector(int size)
{
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> rand_int(INT_MIN, INT_MAX);
std::vector<int> vector;
for (int i = 0; i < size; i++)
vector.push_back(rand_int(rng));
return vector;
}
int main()
{
std::vector<int> vector = randomizeIntVector(100000);
std::vector<int> expectedVector = vector;
quicksort(vector, 0, vector.size() - 1);
std::sort(expectedVector.begin(), expectedVector.end());
assert(vector == expectedVector);
}
可以针对各种向量大小here
测试代码答案 0 :(得分:2)
代码中的两个问题:首先,oldPivot是一个索引,而不是一个枢轴值。该代码将其用作值。将此更改为索引以消除混乱。
第二,对quicksort的调用是在oldPivot的任一侧进行,而不是仅以一种方式进行。
此外,在分配随机向量时,请在内部使用预留空间。
#include <vector>
#include <list>
#include <random>
#include <algorithm>
#include <iostream>
void quicksort(std::vector<int> &list, int left, int right);
int partition(std::vector<int> &list, int pivot, int left, int right);
int randomize_pivot(int left, int right);
std::vector<int> randomizeIntVector(int size);
void print_vector(std::vector<int> v, int left, int right)
{
for (int i = left; i <= right; i++) {
std::cout << v[i] << " ";
}
std::cout << std::endl;
}
void quicksort(std::vector<int> &list, int left, int right)
{
if (left >= right)
return;
int pivot = list[left + (right - left) / 2];
int index = partition(list, pivot, left, right);
quicksort(list, left, index - 1);
quicksort(list, index, right); // prior was 'index + 1', which skipped a cell
}
// Hoare Partitioning Scheme
int partition(std::vector<int> &list, int pivot, int left, int right)
{
while (left <= right) {
while (list[left] < pivot)
left++;
while (list[right] > pivot)
right--;
if (left <= right) {
std::swap(list[left], list[right]);
left++;
right--;
}
}
return left;
}
std::vector<int> randomizeIntVector(int size)
{
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> rand_int(INT_MIN, INT_MAX);
std::vector<int> vector;
vector.reserve(size);
for (int i = 0; i < size; i++)
vector.push_back(rand_int(rng));
return vector;
}
std::vector<int> smallVector(int size)
{
std::vector<int> vector1{5, 4, 1, 2, 3};
return vector1;
}
int main()
{
std::vector<int> vector = randomizeIntVector(100000);
std::vector<int> expectedVector = vector;
quicksort(vector, 0, vector.size() - 1);
std::sort(expectedVector.begin(), expectedVector.end());
assert(vector == expectedVector);
}