Quick Sort

Sort Type: Comparison-Based Sorting / Divide and Conquer Sorting


Algorithm

Description:

The basic idea behind Divide and Conquer Sorting is to divide the data into two smaller groups, sort these, then combine the two small sorted groups into one larger sorted group.


Data holder: Filled array of data structures.

Technique:
  1. Partition the array into two parts based on some arbitraryly selected key. Place all keys less than or equal to the "pivot" key into the left side of the array. Place all keys greater than the pivot key on the right side. The position of the pivot key is not important, only its value. After partitioning the two array sections are not expected to be equal in size.
  2. Recursively call QuickSort() with the left and right halves of the array as long as a subarray contains more than one item.


Analysis: QuickSort runs on the average in O(n log n) time, but in the worst case it runs in O(n2) time. But, this only happens if, on each iteration you always select the pivot key that is the largest or smallest of all the keys in the array. This is something that is very unlikely to happen since the pivot key is selected arbitrarily.

Sample Code:

/***************************************/
/* QuickSort()                         */
/*                                     */
/* Sort records on integer key using   */
/*  a quick sort.                      */
/***************************************/
void QuickSort(StructType DataArray[], int startIdx, int endIdx)
{
    int           i, j;

    if(startIdx < endIdx)
    {
        i=startIdx;
        j = endIdx;
        Partition(DataArray, &i, &j);
        /* On return i will be greater than j */
        QuickSort(DataArray, startIdx, j);
        QuickSort(DataArray, i, endIdx);
    }

}

/***************************************/
/* Partition()                         */
/*                                     */
/* Partition array into two sections   */
/*  for quick sorting.                 */
/***************************************/
void Partition(StructType DataArray[], int *I, int *J)
{
    int           Pivot;    /* Key data */
    StructType    temp;

    Pivot = DataArray[(*I + *J)/2].key; /* Choose an arbidrary pivot point like center of array */
    /* Divide the array into < and > Pivot */
    do
    {
        /* Find leftmost I such that DataArray[I].key > Pivot */
        while(DataArray[*I].key < Pivot) (*I)++;

        /* Find rightmost J such that DataArray[J].key < Pivot */
        while(DataArray[*J].key > Pivot) (*J)--;

        /* If i and J didn't cross over one another, then swap the structs */
        if(*I <= *J)
        {
            temp = DataArray[*I];
            DataArray[*I] = DataArray[*J];
            DataArray[*J] = temp;
            (*I)++;            /* Move i one space to the right */
            (*J)--;            /* Move j one space to the left */
        }
    }
    while(*I <= *J);
}