void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
void QuickSort(int *array, int l, int h)
{
if(l >= h)return;
int pivot = array[l]; /*Pivot is the starting element */
int i = l, temp;
for(int j = l + 1;j <= h;j++)
{
if(array[j] < pivot)
{
i++;
swap(&array[i], &array[j]);
}
}
/*
_______________________i____________________
|pivot|....<=pivot......|....>=pivot......|
*/
swap(&array[i], &array[l]);
/*
____________________i______________________
|...<=pivot......|pivot|....>=pivot......|
*/
QuickSort(array, l, i-1);
QuickSort(array, i+1, h);
}
Although the worst case time complexity of QuickSort is O(n2)
which is more than many other sorting algorithms like Merge Sort and Heap Sort,
QuickSort is faster in practice, because its inner loop can be efficiently implemented on most architectures,
and in most real-world data. quicksort's sequential and localized memory references work well with a cache
Best Case and Average Case: O(nLogn)
QUICK SORT ITERATIVE
int partition (int arr[], int l, int h)
{
int x = arr[h];
int i = l;
for (int j = l+1; j <= h; j++)
{
if (arr[j] <= x)
{
i++;
swap (&arr[i], &arr[j]);
}
}
swap (&arr[i], &arr[h]);
return (i);
}
void quickSortIterative (int arr[], int l, int h)
{
int stack[ h - l + 1 ];
int top = -1;
stack[ ++top ] = l;
stack[ ++top ] = h;
while ( top >= 0 )
{
h = stack[ top-- ];
l = stack[ top-- ];
int p = partition( arr, l, h );
if ( p-1 > l ) {
stack[ ++top ] = l;
stack[ ++top ] = p - 1;
}
if ( p+1 < h ){
stack[ ++top ] = p + 1;
stack[ ++top ] = h;
}
}
}