InspiredCoder
InspiredCoder

Reputation: 404

Quicksort algorithm with duplicate keys

I am trying to implement Quick Sort algorithm. Following code works for unique elements but it doesn't working for arrays having duplicate elements. Please tell me where I am doing wrong. Also when I change value of pivot to some other number other than 0 , program crashes. Here is the code:

#include <iostream>
#include <cstdlib>

using namespace std;

void swapme(int &a, int &b)
{
    int temp = a;
    a = b;
    b = temp;
}

void quicksort(int *arr, int size)
{    
    // these two variables will take care of position of comparison
    int lower = 0, upper = size - 1;  
    int pivot = 0;  // assigns pivot
    if (size <= 1)
        return;

    while (lower < upper)
    {
        while (arr[lower] < arr[pivot])
        {
            ++lower;
        }
    }

    while (arr[upper] > arr[pivot])
    {
        --upper;
    }

    if (upper > lower)
    {
        swapme(arr[upper], arr[lower]);
        // upper--;
        // lower++;
    }

    quicksort(arr, lower);
    quicksort(&arr[lower + 1], size - 1 - lower);
}

int main()
{
    int arr[30];

    for(int j = 0; j < 30; j++)
    {
        arr[j] = 1 + rand() % 5000;
    }

    for(int j = 0; j < 30; j++)
    {
        cout << arr[j] << "\t";
    }
    cout << endl;

    quicksort(arr, 30);

    for(int j = 0; j < 30; j++)
    {
        cout << arr[j] << "\t";
    }
    cout << endl;

    cin.get();
    cin.get();
}

Update: I have finally managed to make it work. Here is the fixed version:

void swapme(int &a, int &b )
{
    int temp = a;
    a = b;
    b = temp;
}

void quicksort(int *arr, int size)
{
    if (size <= 1)
        return;

    // These two variables will take care of position of comparison.
    int lower = 0;
    int upper = size-1;  

    int pivot = arr[upper/2]; // assigns pivot

    while (lower <= upper)
    {
        while (arr[lower] < pivot)
            ++lower;
        while (arr[upper] > pivot)
            --upper;

        if (upper >= lower)
        {
            swapme(arr[upper],arr[lower]);
            if(arr[upper] == arr[lower])
            {
                // Can either increment or decrement in case of duplicate entry
                upper--; // lower++;
            }
        }
    }

    quicksort(arr, lower);
    quicksort( &arr[lower+1], size-1-lower);
}

Upvotes: 3

Views: 7215

Answers (2)

Noor Ul Islam Khattak
Noor Ul Islam Khattak

Reputation: 79

Quick Sort that can implement any number of i/p integers. it also deal with duplicate keys

#include <conio.h>
#include <string>

using namespace std;
void InputArray(int*,int);
void QuickSort(int *,int,int);
int partition(int *,int,int);
void swap(int *,int,int);
void printArr(int *,int Siz=11);

void main(){

    int siz;
    cout<<"Enter Array length   :   "; cin>>siz; 
    int *a=new int[siz];

    InputArray(a,siz);
    QuickSort(a,0,siz-1);
    int i=0,j=11;

    printArr(a,siz);
    system("pause");

}


void InputArray(int*a,int s){
    for(int i=0; i<s; i++){
        cout<<"ELement ["<<i<<"] =  "; cin>>a[i];
    }

}
void QuickSort(int *a,int start,int end){
    if(start<end){
        int pivot=partition(a,start,end);

        QuickSort(a,start,pivot);
        QuickSort(a,pivot+1,end);
    }


}
int partition(int *a,int start,int end){

    int currentPivotValue=a[start];
    int i=start-1, j=end+1;
    while(true){
        i++;
        while(i<j && a[i]<currentPivotValue){ i++; }
        j--;

        while(j>start && a[j]>currentPivotValue) {j--;}
        if(i<j) swap(a,i,j);        
        else return j;
    }


}
void swap(int *b,int i,int j){
    int t=b[i];
    b[i]=b[j];
    b[j]=t;



}
void printArr(int *a,int Siz){
    for(int i=0; i<Siz; i++) cout<<a[i]<<" "; 
}

Upvotes: 0

fredoverflow
fredoverflow

Reputation: 263138

You are storing the index of your pivot element in the pivot variable, so swapping the elements can potentially change the choice of pivot element during the loop. Not a very good idea. I would suggest storing the actual value of the pivot element inside pivot instead.

Also, if this really isn't homework, why don't you simply use the standard library facilities?

#include <algorithm>

// ...

std::sort(arr + 0, arr + 30);

You will get heavily optimized and tested code that will outperform your handwritten Quicksort anytime.

Upvotes: 5

Related Questions