QuickSort无法始终如一地对100 000个整数的数据集进行排序

Quicksort fails to consistently sort data sets of 100 000 integers

本文关键字:整数 数据集 排序 000个 始终如一 QuickSort      更新时间:2023-10-16

我在C 中实现了QuickSort算法的几种变体,但它们都有一个很大的缺陷。他们无法在合理的时间内对100000个整数的数据集进行排序。有时,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);
}

可以在此处对各种向量大小的代码进行测试

代码中的两个问题:首先,old -pivot是索引,而不是枢轴值。该代码将其用作值。将其更改为索引以消除混乱。

第二,对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);
}