C++ 向量快速排序 - 似乎对不同的枢轴有不同的工作方式

Posted

技术标签:

【中文标题】C++ 向量快速排序 - 似乎对不同的枢轴有不同的工作方式【英文标题】:C++ vectors Quicksort - Seems to work differently with different pivots 【发布时间】:2016-01-02 22:58:55 【问题描述】:

当我将枢轴作为第一个、最后一个或中间元素而不是其他一些值时,我的 C++ 向量快速排序算法似乎工作正常。

我不确定所有这些,但例如,如果我将枢轴设置为 (r-l)/2,它将无法正确排序。

我相信我的代码是正确的,但我不确定;可能存在严重错误。

是否有可能有时工作有时不工作,这取决于枢轴?

我以为它只会影响运行时间,所以我猜我的代码有问题。

以下是我的代码:

#include <vector>
#include <algorithm>

using namespace std;

int choosePivot(int l, int r) 
    return (r-l)/2; // or Even r/2


int partition(vector<int>& vec, int l, int r) 
    int pi = choosePivot(l, r); // pivot index
    int pivot = vec[pi];

    // swap pivot with the beginning
    swap(vec[pi], vec[l]); 

    // beginning index of the right side of the pivot (larger than the pivot)
    int i = l + 1;

    // partition around the pivot
    for (int j = l+1; j <= r; ++j) 
        if (vec[j] <= pivot) 
            swap(vec[i], vec[j]);
            ++i;
        
    

    // swap pivot back to its position
    swap(vec[l], vec[i - 1]);

    // return pivot position
    return i - 1;


void quicksort(vector<int>& vec, int l, int r) 
    if (l < r) 
        int p = partition(vec, l, r);
        quicksort(vec, l, p - 1);
        quicksort(vec, p + 1, r);
    


int main() 

    ifstream infile("IntegerArray.txt"); 
    int a;
    vector<int> vec;
    vec.reserve(100000);
    while (infile >> a)
        vec.push_back(a);

    quicksort(vec, 0, vec.size() - 1);

    return 0;

我添加了一个测试示例的 main 函数。

这是IntegerArray.txt

这是一个包含从 1 到 100,000 的所有整数(无重复)的文件。

我编辑了 choosePivot 函数,它会输出一个错误排序的数组。

我没有打印,因为尺寸太大。

【问题讨论】:

您的 median3 是否确实比较了数组中的 indices 而不是 values 您能否提供一个具体的问题示例,而不是在未指定情况下可能以某种未指定方式不正确的代码? 请阅读How to create a Minimal, Complete, and Verifiable example,然后添加缺少的信息。 请告诉我们,错误的结果是什么样子的。这将有助于确定错误的类型。 一个实现的结果不应该依赖于枢纽value的选择。如果pi &lt; l 变为r &lt; pi,你预计会发生什么?。 【参考方案1】:

上面代码中实现快速排序的方式,当主元索引不在lr 之间时会中断。 在这种情况下,它首先从带有swap(vec[pi], vec[l]); 的[l, r] 段之外引入一个值。 这可能会破坏数组中已排序的部分。

现在,(r-l)/2 并不总是介于 lr 之间。 例如,当l = 10r = 20 时,枢轴索引为(20-10)/2 = 5。 因此,代码将通过交换vec[5]vec[10] 开始对[10, 20] 段进行排序。 如果vec[5] 的部分在[10, 20] 段之前排序,这很可能导致数组最终没有排序。

【讨论】:

哦,现在我明白了!所以这是问题所在,而不是代码。

以上是关于C++ 向量快速排序 - 似乎对不同的枢轴有不同的工作方式的主要内容,如果未能解决你的问题,请参考以下文章

对快速排序的理解以及相关c++代码

快速排序 - 中间枢轴实现奇怪的行为

快速排序

C++ 对向量或链表进行排序

如何使快速排序递归?

C++ 按列对二维向量进行排序