Version 05/21/19
Educational Objectives: After completing this assignment, the student should be able to accomplish the following:
Background Knowledge Required: Be sure that you have mastered the following material before beginning the assignment:
Operational Objectives:
(Include 2 and 3 in your log.txt.)
Deliverables: Three files:
list_sort.cpp # slave file of list.h
makefile # builds all your tests
log.txt # your project work log and test diary, contains Operational Objectives 2,3
There are three instances of the bottom-up merge sort algorithm discussed in the lecture notes. All versions of the algorithm require a "merge" utility. In most cases, a target space to hold the merge of two subsets is temporarily required because data cannot be mapped directly back without potentially over-writing other data. The situation for linked lists is better: by unlinking and re-linking data nodes (instead of copying the data inside the nodes) the need for temporary extra space goes away. Here is pseudo-code for a merge operation for subranges in a linked list.
Let L1, L2 be the "input" subranges in the carrier of a linked list and L the "output". The idea is to move entire nodes from the inputs to the output.
initialize pointers p1 to the first node in L1 and p2 to the first node in L2 while (L1 and L2 are not empty) { if (p2->t < p1->t) { q = p2; p2 = p2->next; // "advance" p2 unlink *q from L2 and append it to L } else { q = p1; p1 = p1->next; // "advance" p1 unlink *q from L1 and append it to L } } if (L1 is not empty) append L1 to L; if (L2 is not empty) append L2 to L; // at most one of the last two statements will activate
(The reason for promoting L2 before L1 is that when the values are equal L1 takes precedence over L2.) Here is an illustration:
Before: ------ L1 L2 ------------------- ------------------- [A]->[D]->[E]->[G]->[B]->[C]->[F]->[H]->[]->[]->[]->[] ... ("upper") L: ... []->0 ("lower") After: ----- []->[]->[]->[] ... ("upper") L: ... []->[A]->[B]->[C]->[D]->[E]->[F]->[G]->[H]->0 ("lower") -------------------------------------- L1 merged with L2 appended to L
This is at a stage when you are merging subranges of length 4. You are essentially migrating the links from the top to the bottom. The upper collection gets shorter and the lower collection gets longer as you move along, until at the end all links have migrated from upper to lower picture, and you have completed the step "merge successive pairs of subranges of length 4".
This version of merge facilitates bottom-up merge sort on a linked list as follows:
Loop 1: merge all n/2 successive pairs of subranges of length 1 Loop 2: merge all n/4 successive pairs of subranges of length 2 Loop 3: merge all n/8 successive pairs of subranges of length 4 ... Loop k: merge all n/2k pairs of subranges of length 2k-1 ...
Proceed until only one sublist remains (n ≤ 2k) - which is sorted in place.
There are some loose ends to tie up:
The official development/testing/assessment environment is specified in the Course Organizer. Code should compile without warnings or errors.
In order not to confuse the submit system, create and work within a separate subdirectory cop4531/proj2.
Begin by copying the entire contents of the directory LIB/proj2 into your cop4531/proj2/ directory. Then copy the file LIB/tcpp/list_sort.cpp into cop4531/proj2/. At this point you should see these files in your directory:
list_sort.cpp sortspy.cpp deliverables.sh
Test your sort thoroughly, including collecting and analysing comparision-count data, until you have strong computational evidence that the implementation (1) is correct and (2) runs in time O(n log n).
Be sure that your log.txt contains test results and convincing arguments.
Submit the assignment using the standard submit procedure.
Warning: Submit scripts do not work on the program and
linprog servers. Use shell.cs.fsu.edu to submit assignments. If you do
not receive the second confirmation with the contents of your assignment, there has
been a malfunction.
The file list_sort.cpp that you copied from LIB/tcpp is the starting point for your code. The deliverable has the same name as this file ... so be careful not to re-copy the file in LIB/tcpp over your work.
The sort algorithm implemented in LIB/tcpp/list_sort.cpp is InsertionSort. You are required to replace that implementation with the bottom-up Merge Sort algorithm.
Use a drop-in comp-counting predicate LessThanSpy<T>, as seen in previous courses, to collect data from your List::Sort on data sets ranging in size from small (10) to large (1,000,000). Use these data and clock-time data to provide evidence of the runtime of your implementation.
Most of the sorts tested by sortspy.cpp are in LIB - the exception being the one you are developing.
Attempting to use calls to List::Merge may be problematic, because the subranges being merged are not List objects.