This lab has a variety of goals: To refresh your skills in programming generally, to introduce you to C (including the C compiler), to introduce the topic of sorting, and to start you thinking about how to measure and compare the performance of programs.
In this lab you will write two sorting algorithms and run an experiment to measure one aspect of their performance.
This lab description assumes that you know and remember the essentials of three sorting algorithms: insertion sort, selection sort, and bubble sort. If you need a refresher on any of these, you can find descriptions of them at this old CSCI 235 project description.
The sorting algorithms will rearrange the array they are given (called an in-place or in situ sort)---that's as opposed to returning a new array like the old but sorted. The sorting functions, however, will return something: they will return the number of comparisons made between values in the array. We will use this as a (very primitive) measure of how well the algorithms perform compared to each other.
Make a directory for this lab and move into it.
mkdir lab1 cd lab1
As in most labs and projects, I am giving you some code base to work on. Copy the following files from the course directory for this lab.
cp /homes/tvandrun/Public/cs245/lab1/* .
This gives you six files:
arrayUtil.h
The header file for
the collection of useful array functions.
arrayUtil.c
The implementation file of these functions.
sDriver.c
A program to test the code
you will write.
li> experiment.c
A program to experiment
on the algorithms' performances.
sorts.h
The header file for the
sorting algorithms.
sorts.c
The implementation file for
the sorting algorithms.
The last one of these is the only file that you will need to modify.
First of all, compile the library implementation file and the driver:
gcc -c arrayUtil.c gcc -c sDriver.c
Open sorts.c
in xemacs or gedit.
The first sorting algorithm, insertion sort, is given to you.
Read through it carefully to make sure you understand how it works.
One part is missing, however.
Even though a variable compars
is declared
and its value returned, we never actually
increment it based on the comparisons.
Modify this so that compars
is incremented
whenever we compare two data from the array.
Expressions like i < n
don't count
because they don't compare items in the array.
Now compile it.
gcc -c sorts.c
And link it with the arrayUtil.o
library and
sDriver.o
to make an executable:
gcc sDriver.o sorts.o arrayUtil.o -o sDriver
(I'm giving you all the compilation commands in this lab. However, you'll presumably need to recompile things when you correct your errors--assuming you don't write everything perfectly the first time, which you probably won't. Test yourself on how well you understand the compilation process by determining which compilation commands you need to use when you recompile after making a correction.)
You can test the code using sDriver
by writing the name of the sorting algorithm you want to test in
the command line.
The driver will create a random array, sort it, and
test to see if the result is sorted
(you can inspect the code in sDriver.c
to
see how).
./sDriver insertion
Try this several time. Comparisons will range from around 15 to about 40. If you're not getting in the high 30s some of the time, then you're missing some. (If the driver says the array is not sorted in the end, you've messed something up; ask for help.)
Now implement selection sort in the function selectionSort()
in sorts.c
.
As the algorithm progresses, keep track of comparisons
in the variable compars
.
Then compile and test the revised selection sort.
Obviously you first need to make sure the sorting is correct.
Then make sure you're testing for comparisons correctly.
If you are not getting between 40 and 50 comparisons, then you're
missing some.
You have probably seen another sorting algorithm called bubble sort. While not a very good sort in terms of efficiency, it is easy to program and understand. This algorithm's strategy is to iterate through the array, swapping adjacent values that are out of order.
Clearly one pass through the array of this sort of swapping won't sort the array. Many passes are necessary to put all the elements in the right order. There are two ways to monitor repeated passes: First, one could keep track of whether any changes were made to the array (whether any actual swaps happened) on the current pass; if a pass completes without any swaps, then the array is sorted and we can quit. Second, we can observe the fact that after the first pass through the array, the largest element has made it all the way to the end, and so the next pass can stop one element short; the second pass will put the second largest element in the right place, and so the third pass doesn't need to examine the last two positions; an outer loop, therefore, can count down the ending point of the potentially unsorted portion of the array until that portion is empty.
Implement a version of bubble sort and make sure it sorts correctly.
Now we want to run an experiment to determine
how these algorithms vary in terms of the comparisons
they require.
If we had a little more time today, I would have you write
a program to run this experiment, but since we're sort on time,
I've given it to you completely written.
Open an inspect experiment.c
and figure out how it works.
It runs each sorting algorithm on random arrays
of increasing sizes.
Compile and link:
gcc -c experiment.c gcc experiment.o sorts.o arrayUtil.o -o experiment
Run it:
./experiment
What do you observe?
Leave your code in a gradable state in the directory. The TAs will log in and grade it there.