Inside the Quicksort

The Internet is littered with plenty of good explanations of how the quicksort works. The definition at Wikipedia graphically illustrates the process, which is commonly called “divide and conquer.” I’ve stolen the Wikipedia illustration and placed it into Figure 1.

Figure 1. A graphical illustration of the quicksort process. (Courtesy WikiMedia)

As with a bubble sort, the quicksort eventually gets around to swapping items to order the array elements, but that swapping takes place only when necessary. Contrast that approach with the bubble sort, where all elements are exhaustively compared with each other. That’s why the bubble sort is inefficient.

The quicksort creates a center point or pivot. The algorithm examines values left and right of the pivot. Values are swapped when they’re less than or greater than the pivot point. This process takes place recursively to scan the entire range of values.

Don’t worry if my explanation doesn’t clear the air for you. The bottom line with the quicksort is that a lot less swapping takes place than in a bubble sort.

The following code contains my variation on the quicksort algorithm. Unlike other examples you’ll find on the Interwebs, I tried to make mine readable as opposed to clever.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SIZE 40

void quicksort(int array[], int size);

int main()
{
    int x,original[SIZE],sorted[SIZE];

    srand((unsigned)time(NULL));
    /* populate arrays */
    for(x=0;x<SIZE;x++)
        original[x] = sorted[x] = (rand() % 100)+1;

    /* do the quicksort */
    quicksort(sorted,SIZE);

    /* display the results */
    puts("Org\tSorted");
    for(x=0;x<SIZE;x++)
        printf("%3d\t%3d\n",original[x],sorted[x]);

    return(0);
}

/*
   Quicksort routine
*/
void quicksort(int array[], int size)
{
    int left,right,pivot,temp;

    if(size < 2)            /* stop recursion */
        return;
    pivot = array[size/2];  /* set pivot point, value */
    right = size-1;
    left = 0;
    while(1)
    {                       /* scan for a swapping point */
        while(array[left] < pivot)
            ++left;
        while(pivot < array[right])
            right--;
        if(left >= right)   /* stop if it's not found */
            break;
                            /* swap the values */
        temp = array[left];
        array[left] = array[right];
        array[right] = temp;
        left++;             /* keep looking */
        right--;
    }
                            /* divide and search again */
    quicksort(array,left);
    quicksort(array+left,size-left);
}

In the code, two arrays are created, original[] and sorted[]. Both contain the same values, set at Line 16, but only the sorted[] array is manipulated by using the quicksort() function. That way you can see before and after in the program’s output.

Here is sample output, which I truncated to fit on this webpage:

Org	Sorted
 29	  1
 97	  2
 96	 11
 26	 17
 11	 17
 85	 19
 66	 22
 ...     ...
 30	 93
 48	 95
 22	 96
 72	 96
 46	 97
  1	 97

Of course, you can always use the qsort() function, as demonstrated in last week’s Lesson, which saves a dozen or so lines of code. By viewing the quicksort function in detail, however, you learn more about how it works. It might also help you understand and appreciate recursion.

If you don’t understand recursion, starting by reading my series of Lessons: click here.

In next week’s Lesson, I cover the process of sorting an array of strings by using the qsort() function.

Leave a Reply