【问题标题】:quicksort not sorting c++快速排序不排序C++
【发布时间】:2012-06-27 08:37:54
【问题描述】:

我正在尝试编写一个快速排序函数来对 10 到 1,000,000 个数字之间的任意位置进行排序。它遍历所有内容但不排序,只是按原样打印向量。

由于某种原因,它过早地跳出了while 循环。 我正在使用的测试输入是:(3 6 2 5 1 7 9 10 4 8)。 它的输出:(1 2 6 5 3 7 9 10 4 8)

int main()
{
    std::cout << "Which file would you like to sort?\n";
    std::cin >> file;

    std::ifstream in(file.c_str());

    // Read all the ints from in:
    std::copy(std::istream_iterator<int>(in), std::istream_iterator<int>(),
            std::back_inserter(numbers));

    int max = numbers.size();
    quickSort(numbers, 0, max-1);

    // Print the vector with tab separators:
    std::copy(numbers.begin(), numbers.end(),
            std::ostream_iterator<int>(std::cout, "\t"));
    std::cout << std::endl;

    return 0;
}


void quickSort(vector<int> &numbers, int start, int end)
{
    int i = start;
    int j = end;
    int pivot=numbers[start];
    int temp;
    while( i != j )
    {
        while( numbers[i] < pivot && i < j)
            i++;
        while( numbers[j] >= pivot && i < j)
            j--;

        temp = numbers[i];
        numbers[i] = numbers[j];
        numbers[j] = temp;

        if( j < start )
        {
            quickSort( numbers, start, j );
        }

        if( i < start )
        {
            quickSort( numbers, i, end);
        }
    }
    return;
}

【问题讨论】:

  • 当您在调试器中单步执行程序时,程序的实际状态在什么时候会偏离您预期的状态?
  • 一旦到达temp = numbers[i];,它就会将其设置为“7”,我不太明白为什么。

标签: c++ sorting quicksort


【解决方案1】:

这条线看起来不合适:

int pivot=numbers.size()/2;

无论startend 的位置如何,您都选择numbers 向量的中间元素作为枢轴。

【讨论】:

  • 是的,应该是'int pivot = numbers[(start + end) / 2];'
  • 就我的目的而言,我认为让中间元素成为支点是最有意义的。如果我用pivot = numbers[(start + end)/2]; 替换我拥有的东西,它会用我的代码将枢轴设置为中间元素。
  • @Fourthmeal70 不,对于常规快速排序,常规枢轴是 end-1。
【解决方案2】:

可能除其他外,当您移动索引以查找交换时,您实际上并没有查看向量的内容。本节:

    while( i < pivot && i < j)
        i++;
    while( j >= pivot && i < j)
        j--;

应该改成这样:

    while( numbers[i] < pivot && i < j)
        i++;
    while( numbers[j] >= pivot && i < j)
        j--;

正如其中一位评论者所说,更大的教训是学会使用一个好的调试器来单步调试你的代码。

同样,您应该选择枢轴作为数组值。例如。 pivot = numbers[start]

【讨论】:

  • 它现在至少对几个数字进行了排序。但现在我不明白为什么它不把它们全部排序。我用输入和输出以及更新的代码更新了我的问题。
  • 即使有修复,我认为你仍然有一些问题。我不能推荐足够的学习来使用 gdb 或其他调试器。特别是,我认为对快速排序的两个递归调用应该在 while 循环之外——您首先要进行所有交换,然后在列表的两半上递归。其次,我不明白为什么你在递归之前有if (j &lt; start)。我怀疑你可能想要一个不同的条件。