CPS 100, Spring 2001, Multiset2/Trees

This assignment is worth 20 points.
See the FAQ

This assignment is designed to give you practice with inheritance and trees. For extra credit you'll explore the relationship between tree-traversals (inorder, preorder, postorder) and tree construction.

Summary of What To Do

Details are given below, the list here shows you what steps you must do to complete the assignment.
  1. Implement a new MSApplicant abstract base class and child/sub classes MSPrinter and MSTotal.
  2. Add a pure virtual function applyAll to the Multiset base class that uses an MSApplicant object (described more below). Implement the new member function for both the LinkedMultiset and TableMultiset and test this in a modified version of readwords.cpp that's given to you.
  3. Implement a new class Tree that has a similar interface to your LinkedList class.
  4. Implement a new sub-class of Multiset, TreeMultiset, that implements the multiset interface.
  5. Time how long the different implementations of multisets take to process several files and explain the differences you find.

  6. Extra Credit: experiment with different implementations of TreeMultiset::applyAll and reason about the implementations.

You will be given one new file for this assignment, a new implementation of readwords.cpp that can be found in ~ola/cps100/multiset2/readwords.cpp on the acpub system. You'll need to use the code you wrote for part 1 of the assignment. However, you should make a copy of your code for this new assignment. To do this you should create a directory cps100/multiset2. You should then copy all the files from your old directory to your new directory:

  cp ~/cps100/multiset ~/cps100/multiset2
Then copy the new version of readwords.cpp from ~ola/cps100/multiset2.


1. The class MSApplicant

What to do

You must create files for three classes.

Details

Recall from last week's discussion section the class MSApplicant that serves as an interface/base class for classes that can be passed to a Multiset::applyAll function. For example, to print a multiset you won't have a print function as part of the Multiset class, you'd do something similar to the code below. The class MSPrinter is a subclass of MSApplicant. The function MSPrinter::applyOne would print one line of output as discussed in recitation section.

MSPrinter printer; LinkedMultiset set; // fill set with values set.applyAll(printer); The parent class MSApplicant is shown below. Note that every base class must have a virtual destructor and that the class is abstract because the function MSApplicant::applyOne is pure virtual. This code and more discussion were part of inheritance lecture notes. class MSApplicant { public: virtual ~MSApplicant() { } virtual void applyOne(const string& word, int count) = 0; };

2. The applyAll functions

What to Do

Implement applyAll and test it (and the code you wrote for MSTotal and MSPrinter) by compiling and running the new version of readwords.cpp you're given.

Details

You should add a prototype for Multiset::applyAll to the class declaration in multiset.h. The function applyAll should be pure virtual as shown. virtual void applyAll(MSApplicant& applicant) = 0;

You should remove the prototypes for functions Multiset::print and Multiset::total since these will be replaced by using Multiset::applyAll and the MSApplicant subclasses MSPrinter and MSTotal you wrote in the first part of this assignment.

In all subclasses of Multiset (this includes LinkedMultiset and TableMultiset) implement applyAll and remove the implementations of total and print.

As we discussed in class and recitation, the applyAll should call MSApplicant::applyOne on each element in the multiset. This means, for example, that for the class LinkedMultiset you should be able to implement applyAll by changing one line of your print implementation. Instead of printing, call MSApplicant::applyOne:

applicant.applyOne(current->info, current->count);

Be sure to test both LinkedMultiset::applyAll and TableMultiset::applyAll in different compiles/runs of readwords.cpp.


3. Trees

What to Do

Implement a class Tree that's an analog of the class LinkedList, but which provides users/clients with a simple class to search for and add values to a binary search tree.

Use this class Tree to implement a new class TreeMultiset that uses binary search trees as the basis of the multiset. Use this class in readwords.cpp and compare timings with other Multiset implementations.

Details

Class Tree

You should implement a class Tree by writing both tree.h and tree.cpp. This class is an analog of the class LinkedList in providing a simple interface to a binary search tree as that class provided a simple interface to a linked list.

Your Tree class should include member functions for

These functions will be public as will a Tree::Node struct you write that's just like the Node struct in the class LinkedList, but in the tree class the pointers should be labelled as left and right rather than next and prev.

We've gone over code in class for searching for a value and for adding values to a search tree. These should be the basis for the member functions you write for adding and searching. The other functions (construction, size, returning root) are all one line functions (the constructor should use an initializer list). The root of the search tree should be set to NULL/0 when the tree is contructed.

You can write a test program to test this tree class (like the program testlink.cpp) but this isn't required. If you do write a test program, you should note this in your README, and submit it for extra credit.

Class TreeMultiset

Implement a class TreeMultiset that uses search trees for storing values. This class and its relationship to the class Tree are similar to the relationship between classes LinkedMultiset and LinkedList.

You should write the interface to the class in treemultiset.h and the implementation in treemultiset.cpp. The class will be similar to LinkedMultiset but you'll need one (at least) helper function for implementing applyAll.

Here's the code for TreeMultiset::applyAll

void TreeMultiset::applyAll(MSApplicant& applicant) // post: all values of multiset are proceseed via applicant { applyHelp(myTree.getRoot(), applicant); }

The code for TreeMultiset::applyHelp should use a standard inorder tree traversal for visiting all nodes of the tree and calling applicant.applyOne for each node visited. If you do this and use a TreeMultiset in readwords.cpp to test the implementation you should get words printed in alphabetical order.

4. Extra Credit

Implement an MSApplicant subclass called MSCopy that makes a copy of a Multiset. This class will be similar to one you wrote in week4 recitation, but you'll construct an MSCopy object from a Multiset and create the copy in that Multiset. This will let you copy from one multiset to another even if they're implemented differently (eg. with Tree, Table).

The idea is for client code to create an empty multiset (say eSet), construct an MSCopy object using eSet, then pass the MSCopy object to the multiset to be copied.

Multiset * set = new TableMultiset(); // add values to set Multiset * eset = new TreeMultiset(); MSCopy copy(eset); set.applyAll(copy); // now eset is a copy of set, but they are different kinds of sets

Note that the set used to construct the MSCopy object is filled with values as a result of calling set.applyAll(copy) in the code above.

After implementing this class MSCopy you should develop a program similar to readwords.cpp but which you'll use for timing and testing the copying. Read words from a file and put them in a TreeMultiset. Then make a copy of the multiset using an MSCopy object. You'll then have two tasks:


Grading

The table below indicates how much each part of the assignment is worth.
CodePoints
MSApplicant/subclasses 4
applyAll 2
Tree class 5
TreeMultiset 5
README/comments/style 4 Extra Credit tree test 3
Extra Credit copy/traversal 5

Submit

Use
  submit_cps100 multiset2 *.cpp *.h Makefile README

So that you submit all your .h and .cpp files, your README file, and a Makefile that compiles your program into an executable named readwords.

If submit_cps100 doesn't work, try ~ola/bin/submit100


Owen L. Astrachan
Last modified: Sat Feb 17 15:40:40 EST 2001