Lab 2: Shell sort, merge sort, and experimentation

John Murdoch: Here, let me ask you a question. You heard of a place called Shell Beach?
Inspector Frank Bumstead: Sure.
John Murdoch: Do you know how to get there?
Inspector Frank Bumstead: Yeah.
John Murdoch: Tell me.
Inspector Frank Bumstead: Right. You just... you go to the...
John Murdoch: Where? Where do you go?
Inspector Frank Bumstead: Just give me a second, will you...
John Murdoch: You can't remember, can you?
---
John Murdoch: Hey, do you know the way to Shell Beach?
Taxi Driver: You're kidding! Me and the Mrs. spent our honeymoon there. All you gotta do is take Main Street West to... or is it the Cross... You know, that's funny, I can't remember if it's Main Street West or the Crosstown.
---Dark City

The goal of this lab is to give you more practice programming in C and working with the C compiler, to demonstrate three other sorting algorithms, 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/* .

The given files are

Note that I am giving you the makefile for this lab. In some future labs and projects, you will need to modify a makefile or write your own from scratch. Open the makefile in a text editor and talk through it with your partner; review what we talked about in class and make sure you understand it, anticipating writing your own sometime in the future.

2. Shell sort

Your first 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.)

To implement this, we will use an incremental approach in which you will test your program using the sort driver. To compile at test at each step, use the make command. When your code compiles, use ./sort_driver to test various sorting algorithms for correctness. Try this out now.

make
./sort_driver selection
./sort_driver bubble

Each test should report that "All tests pass." If you're not getting that message, ask for help.

Now test Shell sort (yes, I mean that; even though you haven't written it yet).

./sort_driver shell

You should see many failure messages about tests that did not pass. That's good, becuase you haven't written shell sort yet. If it passed all the tests before you wrote it, then there would be something seriously wrong with your testing apparatus. (If you aren't getting a screenful of failure messages, ask for help.)

Here are the steps:

3. Merge sort

You may remember the merge sort algorithm from Programming I. In brief the algorithm sorts by

In sorts.c, we divide the task into three functions:

A. Merging

We did this function in class last week. Review it now. Its prototype is int merge(int array[], int helper[], int start, int stop). Notice that it receives a helper array as well as array. The helper array is the destination for the merging, since we can't merge in-place. Formally for this function:

PRECONDITION: The subarrays in array[start, midpoint) and array[midpoint, stop) are sorted, where midpoint is halfway between start and stop.

POSTCONDITION: The range helper[start, stop) contains the values from array[start, stop) in sorted order.

RETURN: The number of comparisons.

Notice that merge() does not copy the values back to array. When merge() returns, array is unchanged.

The Implementation of merge() is given for you. You can test it in isolation with a separate driver:

make merge_driver
./merge_driver

B. Implementing the recursion

When merge() is working, then write mergeSortR(). Notice that it, too, receives a helper array, which it will pass on to merge(). When merge() returns, it is the responsibility of mergeSortR() to copy values back from helper to array.

You can test it with the main driver.

make sort_driver
./sort_driver merge

Don't forget to add code to count the number of comparisons. The actual comparisons will all happen in merge() but mergeSortR() needs to sum and return them.

4. Insertion sort

We have talked about insertion sort in class. A partially-written implementation is given for you in sorts.c. Finish this by writing the inner loop, which inserts an element into the right position of the sorted section. The hard part is the guard of the loop. Think carefully about this.

Test your implementation:

make sort_driver
./sort_driver insertion

5. Experiments

Now open the file experiment.c. Inspect it with your partner and figure out what is going on and how it is using the array_util library. Ask if there is anything you don't understand. Remember you will need to write your own experiment in Project 1.

Compile and run the experiment. You may want to run it several times to see how much variation there is on different runs. What do you observe about the running times of the various sorting algorithms?

6. To turn in

Write a brief (paragraph-sized) summary of what you observed in the experiments in a file called EXPERIMENTS. Make sure your names appear in the files that the grader will inspect.


Thomas VanDrunen
Last modified: Thu Jul 30 16:22:26 CDT 2015