Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Quick Sort - Middle Pivot implementation strange behaviour

I am trying to implement quick sort with pivot value as middle element of the vector using various tutorials available online. Even though it's working for some samples there's one where I am not able to get sorted vector.

Example - Input {5,3,8,6,1,0,4} but output is {0,3,4,5,1,6,8}

QuickSort implementation

void quickSortMiddle(vector<int> &a, int left, int right)
{
    if(left >=right) return;

    int leftI = left;
    int rightI = right;

    int pivot = left + (right - left)/2;

    while(leftI<=rightI)
    {
        while(a[leftI] < a[pivot] )leftI++;
        while(a[rightI] > a[pivot])rightI--;

        if(leftI <=rightI)
        {
            swap(a[leftI], a[rightI]);
            leftI++;
            rightI--;
        }
    }

    if(left <= rightI)quickSortMiddle(a,left,rightI);
    if(leftI <= right)quickSortMiddle(a,leftI,right);
}

Following is the output I am getting after every implementation

5340168

0345168

0345168

0345168

final : 
0345168
like image 874
dasa Avatar asked Dec 28 '25 05:12

dasa


1 Answers

The issue is using a[pivot] rather than setting pivot = a[left + (right - left)/2]. Your version with this fix:

void quickSortMiddle(vector<int> &a, int left, int right)
{
    if(left >=right) return;
    int leftI = left;
    int rightI = right;
    int pivot = a[left + (right - left)/2]; // set pivot to value
    while(leftI<=rightI)
    {
        while(a[leftI]  < pivot )leftI++;   // use pivot by value
        while(a[rightI] > pivot )rightI--;  // use pivot by value
        if(leftI <=rightI)
        {
            swap(a[leftI], a[rightI]);
            leftI++;
            rightI--;
        }
    }
    if(left < rightI)quickSortMiddle(a,left,rightI); // < not <=
    if(leftI < right)quickSortMiddle(a,leftI,right); // < not <=
}

Standard Hoare partition scheme, although your version works fine with the pivot fix:

void quickSortMiddle(vector<int> &a, int left, int right)
{
    if(left >= right) return;
    int pivot = a[left + (right - left)/2];
    int leftI = left-1;
    int rightI = right+1;
    while(1)
    {
        while(a[++leftI] < pivot);
        while(a[--rightI] > pivot);
        if(leftI >= rightI)break;
        swap(a[leftI], a[rightI]);
    }
    quickSortMiddle(a,left,rightI);
    quickSortMiddle(a,rightI+1,right);
}
like image 117
rcgldr Avatar answered Dec 30 '25 19:12

rcgldr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!