Lab 2: Instrumentation

The goal of this lab is to give you more practice programming in C and working with the C compiler, to demonstrate another sorting algorithm, and to to study the efficiency of sorting algorithms experimentally, comparing the results with the theoretical findings of complexity analysis.

1. Set up

Make a directory for this lab and move into it. Copy given the code from the course directory.

mkdir lab2
cd lab2
cp /homes/tvandrun/Public/cs245/lab2/* .

As with last time, the given files are

Look over each .c and .h file so you understand how they work together. Then inspect the makefile and discuss it with your partner so you understand what it does and how. In a future lab or project, you will write your own makefile. Understand this one well enough that you can produce something similar for a project of your own.

2. Counting comparisons

The sorting algorithms we saw in class are already implemented in sorts.c. The functions also return an int intended to be interpreted as the number of comparisons. However, these functions do not actually return the number of comparisons--- they just return 0. Your first task is to modify them so that they count and return the number of comparisons.

Specifically, we're interested in the number of times we compare two data from the array-- that is, the number of times an expression like min > array[j] is evaluated. Expressions like i < n don't count because they don't compare items in the array.

Use the makefile to comiple and the driver to test. To use the driver, give the name of the sorting algorithm and the number of elements in the array, for example

./sDriver selection 15

If you do not give the number of array elements, the default is 10 elements. This will print out the array before and after sorting (if the size is 20 or fewer), report on whether the sorting is correct, and report on the number of comparisons.

3. Shell sort

Your next task is to implement yet another sorting algorithm, called Shell sort. Suppose we have the array

49 7 83 22 8 45 72 91 22 80 53 88 43 29 14 35 55 24 37 84

First consider the items separated by 7 spaces, starting at 0.

49 7 83 22 8 45 72 91 22 80 53 88 43 29 14 35 55 24 37 84

Sort them.

14 7 83 22 8 45 72 49 22 80 53 88 43 29 91 35 55 24 37 84

The items separated by 7 starting at 1 are already sorted.

14 7 83 22 8 45 72 49 22 80 53 88 43 29 91 35 55 24 37 84

Sort the next bunch.

14 7 83 22 8 45 72 49 22 80 53 88 43 29 91 35 55 24 37 84
14 7 55 22 8 45 72 49 22 80 53 88 43 29 91 35 83 24 37 84

Keep doing that until all the array slices with gap 7 are sorted. The actual sorting can be done using a modified insertion sort. Then, we decrease the gap and repeat the process, say sorting all the slices with gap 3. Finally, sort with gap 1, which is just insertion sort, except that this should be close to the best case for insertion sort because the items by now are nearly sorted.

(It might be tempting to call these sections "shells" and pretend that's where the name of the sort comes from. Actually the algorithm was invented by someone named Donald Shell.)

Implement Shell sort using the stub in sorts.c You can use your code from insertion sort as a starting point. You'll need to wrap it in two more loops: one to iterate through the various starting points for the current gap, and an outermost one to iterate through the gaps.

In theory, any decreasing sequence can be used for the gaps, but the last gap must be 1. Also, make sure that you use gap 1 only once (or you'll probably end up with an infinite loop) and don't use gap 0.

Your implementation should also count and return the number of comparisons.

Compile and test. Make sure you test not only one arrays of size 10 but also on large arrays.

4. Experiments

Now you want to compare the sorting algorithms against each other. Write a program to run an experiment: How do the number of comparisons increase as a function of the size of the array? For each of several array sizes (for exampe, 10, 50, 100, 500, 1000, 5000...), make a random array. Run each sorting algorithm on that array and determine the number of comparisons. Display the results.

As an example of how you would write a program that runs an experiment, suppose you decided to run selection sort on 10 arrays for each size 10, 50, 100, 500, 1000, and 5000, you might write something like

     int i, j;
     int* array;
     int sizes[] = {10, 50, 100, 500, 1000, 5000};
     for ( i = 0; i < 6; i++)
          for (j = 0; j < 10; j++) 
           {
             array = randomArray(sizes[i]);
             selectionSort(array);
          }

But in your experiment, you want to run several sorting algorithms on the same array. (Remember that you can make a copy of an array using copyArray() from the arrayUtil I've given you. You don't want to simply sort the array with the first algorithm and then give a sorted array to the subsequent algorithms.)

5. To turn in

Instead of a hard-copy turn in, the TA will log into the lab account and grade your code and results there.


Thomas VanDrunen
Last modified: Thu Sep 6 14:37:06 CDT 2012