Shell Sort

Sort Type: Comparison-Based Sorting / Diminishing Increment Sorting


Algorithm

Description:

Shell Sort subdivides the array of structures to be sorted into smaller pieces by selecting every nth record and then sorting that group of sturctures. By repeatedly reducing the value of n until it diminishes to 1 the array becomes sorted. The efficiency of Shell Sort comes from the fact that it is able to move structures which are greatly offset from their final location rapidly with few key comparisons.


Data holder: Filled array of data structures.

Technique:
  1. Calculate a set of delta's. Usually calculated as n/3 (where n is the number of records in the array) for the first iteration, then each succeeding delta is delta = 1 + delta/3 (using integer math each time).
  2. Starting at the beginning of the array, take every delta structure and sort that group, as if it were a sub-array, using an insertion sort technique.

    In this diagram 5 sets of structures are sorted when delta = 5
  3. Repeat until delta == 1

Analysis: Oddly enough even though this uses the insertion sort technique which has a worst case run time of O(n2) the way this sort algorithm divides up the sorting into small groups which moves structures a long distance in the array, this algorithm runs in O(n1.25) time.

Sample Code:

/***************************************/
/* ShellSort()                         */
/*                                     */
/* Sort records on integer key using   */
/*  a shell sort.                      */
/***************************************/
void ShellSort(StructType DataArray[], int count)
{
    int i, delta;

    delta = count;

    do
    {
        delta = 1 + delta / 3;
        for(i=0; i<delta; i++)
            DeltaInsertionSort(DataArray, i, delta, count);
    }
    while(delta > 1);
}

/***************************************/
/* DeltaInsertionSort()                */
/*                                     */
/* Sort subarrays of records on integer*/
/*   key using selection sort.         */
/***************************************/
void DeltaInsertionSort(StructType DataArray[], int I, int Delta, int count)
{
    int            j, k;
    int            key;
    int            NotDone;
    StructType    temp;

    j = I + Delta;

    while(j < count)
    {
        key = DataArray[j].key;        /* Get next key to sort */
        temp = DataArray[j];    /* Remove and hold */

        /* Do insertion sort on this key in the block of delta records */
        /* Move each struct where DataArray[j].key > key to the right  */
        /*   by delta spaces and insert the key there.                 */
        k = j;
        NotDone = TRUE;

        do
        {
            if(DataArray[k - Delta].key <= key)
                NotDone = FALSE;    /* Terminate the loop */
            else
            {
                DataArray[k] = DataArray[k - Delta];
                k -= Delta;
                if(k==I) NotDone = FALSE;
            }
        }
        while(NotDone);

        /* Insert the moved key */
        DataArray[k] = temp;

        /* Get next key to insert--one full delta increment to the right */
        j += Delta;
    }
}