UCSC BME 194 Winter 2004

Resource-efficient Programming

Program Assignment 3 (quicksort)

(Last Update: 18:22 PST 17 January 2004 )
The quicksort algorithm is really a large class of closely related algorithms, all with somewhat different running times. In this assignment you will implement a few variants of quicksort and time them. To make the differences in implementation more obvious, we'll do quicksort on integer keys with no associated data, since that uses a very fast comparison, and the effect of overhead will make a bigger relative difference.

Your task will be to write, document, and debug several variants of the quicksort algorithm, and do timing tests comparing the algorithms. You will also do the timing tests on the c-library routing qsort, and (for short arrays) on insertion sort.

Start by writing an insertion sort routine:

    void insert_sort(int *A, unsigned int length)
Time this routine for small lengths on random arrays (say n=0 to n=50), and provide a table and plot of the times. To make the timing more repeatable, you might want to create one large random array, and write a tight loop sorting subarrays, avoiding the overhead of doing a clock() call for each call to the sort routine.

Get your insertion sort and timing framework done before you start work on quicksort.

Implement a sort using the library qsort() routine. All you need for this is a comparison function. Time the qsort routine sorting small arrays (n=0 to 50, again) and large ones (n=1024, 2048, ..., 2^20)

Write your quicksort routines to do in-place sorting in ascending order. The quicksort routine should look something like

	
void quicksort(int *A, unsigned int length)
{
    int num_in_first;
    switch(length)
    {    case 0: return;
    	 case 1: return;
    }
    num_in_first = partition(A,length);
    quicksort(A, num_in_first);
    quicksort(A+num_in_first, length-num_in_first); 
}

You will have to write your own partition function. There are many different variants on partition that you can find in various textbooks. For now, you may pick any of them, as long as your pivot choice is sensible (say the middle element of the array, not the first element).

Time your quicksort routine for small arrays (sort the same random arrays that you sorted with insertion sort---it is probably easiest to make two copies of the large random array and sort one with insertion sort, one with quicksort). Plot the insertion sort and quicksort data on the same graph. Play around with gnuplot until you find a good way to compare the two visually. For example, I found it useful to make the x-axis be the length of the array to sort, and the y-axis be the ratio of the microseconds/call.

Try improving your quicksort by adding the following code to the base case:

    if (length < INSERT_FASTER_IF_SHORTER) 
    {   insert_sort(A,length);
        return;
    }
with an appropriate setting of the constant INSERT_FASTER_IF_SHORTER. Re-time your improved quicksort.

To turn in

Turn in your timing program (time-sort.c), a README file describing your experiments, an output file (time-sort.out), and a gnuplot script to create your graphs (time-sort.gnuplot). If you want to hand in a PDF file that has the text and the graphs nicely formatted, call it time-sort.pdf.

Bonus points

You can earn bonus points (if you have time) by exploring more of the optimization space. For example, you could

slug icon to go to School of Engineering home page SoE home     UCSC Bioinformatics Home Page     BME 194 home page    

Questions about page content should be directed to

Kevin Karplus
Computer Engineering
University of California, Santa Cruz
Santa Cruz, CA 95064
USA
karplus@soe.ucsc.edu
1-831-459-4250