Hoare's partition not working correctly (quicksort)

时间秒杀一切 提交于 2019-12-08 04:57:19

问题


So after following the quicksort and hoares partition algorithm from Cormen, this is the code that I was able to produce. The array comes out partly sorted with uninitialized elements/garbage elements and I can't for the life of me figure out why... I thought I followed the algorithm exactly as the book writes it.

Here is the pseudocode straight from the book:

HOARE-PARTITION(A, p, r)
1 x = A[p]
2 i = p - 1
3 j = r + 1
4 while TRUE
5     repeat
6        j = j - 1
7     until A[j] <= x
8     repeat
9        i = i + 1
10    until A[i] >= x
11    if i < j
12        exchange A[i] with A[j]
13    else return j

And here is the C++ code I translated it into:

void quickSort(int arr[], int p, int r){
    if(p < r){
        int q = hoare_partition(arr, p, r);
        quickSort(arr, p, q-1);
        quickSort(arr, q+1, r);
    }
}

int hoare_partition(int arr[], int p, int r){
    int x = arr[p];
    int i = p - 1;
    int j = r + 1;
    while(true){
        do{
            j--;
        }while(arr[j] > x);
        do{
            i++;
        }while(arr[i] < x);
        if(i < j){
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        else 
            return j;
    }
}

Im using the following to test it

cout << endl << endl << "Testing quicksort" << endl;
int tarr[10] = {2, 30, 1, 99, 46, 33, 48, 67, 23, 76};
quickSort(tarr, 0, 10);
cout << "arr after quicksort: ";
for(int i = 0; i < 10; i++){
    cout <<  tarr[i] << " ";
}
cout << endl;

The output

arr after quicksort: -2146162183 1 2 23 30 33 46 48 67 76

Any help is appreciated ahead of time...thanks

EDIT

Changing the test case call to quickSort(arr, 0, 9) fixed it for this situation.

However, with a reverse sorted array as the input this is the output:

arr2 is:
30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
arr2 after quicksort :
1 3 5 7 9 11 13 15 17 19 20 21 18 22 16 23 14 24 12 25 10 26 8 27 6 28 4 29 2 30

using this test code:

int arr2[30];
fillArrayReverse(arr2, 30);
cout << "arr2 is :" << endl;
for(int i = 0; i < 30; i++){
    cout << arr2[i] << " ";
}
cout << endl;
quickSort(arr2, 0, 29);
cout << "arr2 after quicksort: " << endl;
for(int i = 0; i < 30; i++){
    cout << arr2[i] << " ";
}
cout << endl;

回答1:


It's a problem with your test code. The third parameter should be the index of the last element, not the number of elements:

quickSort(tarr, 0, 9);

You're reading past the end of the array.

For more information about Hoare partitioning, Quicksort and Cormen etc, see this question.

The simple fix for the other problems you're having is to change hoare_partition() to return i instead of j. See the link for more details (it's an error in the book reportedly).




回答2:


The psuedocode in the book is correct. The issue is not that j was returned (this was correct), but in the quickSort function itself. It should actually read as follows:

void quickSort( int arr[], int p, int r )
{
    if( p < r )
    {
        int q = hoare_partition( arr, p, r );
        quickSort( arr, p, q );
        quickSort( arr, q + 1, r );
    }
}

Note that we remove q - 1 in the first call to quickSort, and replace it with just q. Beforehand we were essentially skipping the pivot point and only sorting items around it. I noticed this discrepancy after taking a look at the Hoard Partition psuedocode on quick sort on wikipedia.



来源:https://stackoverflow.com/questions/29025158/hoares-partition-not-working-correctly-quicksort

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!