快速排序无法正常工作

时间:2015-11-15 01:35:09

标签: c++ pointers pivot quicksort partition

我在代码中找不到问题。它运行,但它无法正确排序数组。我认为最令我困惑的部分是如何在递归过程中传递未排序的子数组。

#include<iostream>
using namespace std;

void quickSort(int*, int, int);
int partition(int*, int, int);

int main(){
    int const size = 10;
    int a[size] = {37, 2, 6, 4, 89, 8, 10, 12, 68, 45};

    for(int i=0; i<size; i++){
        cout << a[i] << " ";
    }
    quickSort(a, 0, size-1);
    cout << endl;   
    for(int i=0; i<size; i++){
        cout << a[i] << " ";
    }

}

void quickSort(int *array, int start, int end){
    if(start<end){
        int piv = partition(array, start, end);
        quickSort(array, 0, piv-1);
        quickSort(array, piv+1, end-1);
    }
}

int partition(int *array, int start, int end){
    int piv = array[start];
    int i = start+1;
    int j = end;
    while(i<j){
        while(array[i]<piv and i<end) i++;
        while(array[j]>piv) j--;
        if(i<j){
            int temp = *(array+i);
            *(array+i) = *(array+j);
            *(array+j) = temp;
        }

    }
    int temp = *array;
    *array = *(array+j);
    *(array+j) = temp;
    return j;
}

输出如下:

    37 2 6 4 89 8 10 12 68 45
    4 6 8 10 12 37 68 89 2 45

2 个答案:

答案 0 :(得分:0)

请注意,end 包含,因此您不应在end-1上进行递归,而应end

你的partition()函数犯了一些错误:

  • 在嵌套的while循环中,您应该检查i<j,而不是i<end
  • 在嵌套的while循环中,您应首先检查i<j,然后再将该元素与piv进行比较。
  • 在循环之后,您应该检查j是否指向元素&gt;是piv还是不。如果是,则需要在执行交换之前递减j。考虑:
     37 2 6 4 12 8 10 89 68 45
                      j
     89 2 6 4 12 8 10 37 68 45 
  • 在循环之后,总是与整个数组中的 first 元素交换。我确定您意味着array[start]交换。

顺便说一下,*(array+j)array[j]相同。

希望这有帮助。

答案 1 :(得分:0)

我注意到的第一件事是:

"[{\"field\":\"Email:1\",\"title\":\"email\",\"explanation_text\":\"\",\"explanation_text_location\":\"\",\"html_styling\":\"\",\"text_to_display\":\"\",\"show_title_field\":\"\",\"pdf_file\":\"\",\"pdf_file_button_styling\":\"\",\"pdf_file_button_text\":\"\"}]" 

应该是:

    quickSort(array, 0, piv-1);
    quickSort(array, piv+1, end-1);

之后,我认为通过在代码中的关键位置添加 quickSort(array, start, piv-1); // start, not 0 quickSort(array, piv+1, end); // end, not end-1 语句来更容易识别问题的根源。这就是我试过的:

cout

有了这些,我得到了以下输出:

void quickSort(int *array, int start, int end){

    if(start<end){
       cout << "Before sort: ";
       for(int i=start; i<=end; i++){
          cout << array[i] << " ";
       }
       cout << std::endl;
        int piv = partition(array, start, end);
        std::cout << "Pivot index: " << piv << ", Pivot element: " << array[piv] << std::endl;
        quickSort(array, start, piv-1);
        quickSort(array, piv+1, end);
    }

    cout << "After sort: ";
    for(int i=start; i<=end; i++){
       cout << array[i] << " ";
    }
    cout << std::endl;
}

这让我在37 2 6 4 89 8 10 12 68 45 Before sort: 37 2 6 4 89 8 10 12 68 45 Pivot index: 6, Pivot element: 37 Before sort: 10 2 6 4 12 8 Pivot index: 4, Pivot element: 10 Before sort: 8 2 6 4 Pivot index: 3, Pivot element: 8 Before sort: 4 2 6 Pivot index: 1, Pivot element: 4 After sort: 2 After sort: 6 After sort: 2 4 6 After sort: After sort: 2 4 6 8 After sort: 12 After sort: 2 4 6 8 10 12 Before sort: 89 68 45 Pivot index: 9, Pivot element: 2 Before sort: 89 68 Pivot index: 8, Pivot element: 45 After sort: 89 After sort: After sort: 89 45 After sort: After sort: 89 45 2 After sort: 68 4 6 8 10 12 37 89 45 2 68 4 6 8 10 12 37 89 45 2 看得更近了,我注意到你有:

partition

这解释了为什么分区数组的下半部分中的数字被拉入分区数组的上半部分。他们应该是:

int temp = *array;
*array = *(array+j);
*(array+j) = temp;

使用它更具可读性:

int temp = *(array+start);
*(array+start) = *(array+j);
*(array+j) = temp;

通过这些更改,阵列出来了。