(Latest Revision: 11/19/99)
11/10/99: Took out a piece of purposeless information about how
to create a deck of index cards.
11/19/99: Moved back the due date from 11/22 to 11/24
BOOK-COLLECTION PROGRAM
DUE DATES:
- Level 03 Program Due Monday, Nov 15. Turn in copies of all
your source files plus a script showing your test runs. You
must demonstrate adequate testing of the program. You must
shar all these materials into a single archive file and
send them via e-mail before midnight, or they will be
considered late and will not be accepted.
- Final Level Program Due Wednesday, Nov 24. Turn in copies of
all your source files plus a script showing your test runs. You
must demonstrate adequate testing of the program. You must
shar all these materials into a single archive file and
send them via e-mail before midnight, or they will be
considered late and will not be accepted.
Please read the class documents entitled:
programAssignmentRules,
sampleProgramSubmission-level01,
sampleProgramSubmission-level02,
sampleProgramSubmission-level03,
howToMakeTestScript-level01,
sampleTestScript-level01,
sampleTestScript-level02, and
sampleTestScript-level03
before beginning to do this programming assignment. You will
find the documents under "CourseDocuments" in the class
web space. Also, be sure to ask questions in class!
Write a simple program to maintain a list of books for a
personal library.
Basically, the program must accept commands to make insertions
and deletions in the list, and simultaneously maintain the list
in alphabetical order for THREE keys: title, author, and
subject.
DATA STRUCTURES:
You can simulate an "index card" containing information about a
book as a C struct. Here is a C declaration that illustrates:
#include <string>
typedef struct
{
string title ;
string author ;
string subject ;
}
indexCardType ;
The list structure of the implementation must be that of a
binary search tree. Since there are three keys, the structure
will actually be a "multi-tree." You must use three sets of
pointers: left and right title; left and right author; and left
and right subject.
When the program adds another book to the collection it
allocates a node that contains room for the book information
and the three sets of pointers. It then copies the book
information (title, author, and subject) into the node and
links the node into the multi-tree -- really three trees in one.
INPUT:
This program will begin with an empty list, and will accept
commands from the standard input to insert, delete, list the
cards in order by one of the keys, or quit.
In order to make the program easy for me to test, it must be
able to work correctly when operated using indirection. For
example, I want to be able to test your program by typing
a.out < mytestinputfile > mytestoutputfile
where mytestinputfile is a file containing a series of the
commands described in the next section. I don't have time to
do much testing in "interactive mode".
COMMANDS:
Input to the program will consist of a series of commands in
the following forms.
Note: arguments like <subject> stand for VARIABLES which are
strings terminated by end-of-line. Strings will have arbitrary
amounts of leading, embedded, and trailing white space. The
internal representation of the strings however are required
*not* to have leading or trailing whitespace, and to have only
single blanks between "words." (Here, a "word" is a contiguous
string of characters that are not white space -- so something
like the L. in L. Frank Baum would be called a word.)
Command names given below, like Insert, are literals and will
appear in the input file exactly as they appear below.
COMMAND FORM:
Insert <author>
<title>
<subject>
SPECIFIC EXAMPLE:
Insert L. Frank Baum
The Wizard of Oz
Children's Fantasy
As stated earlier, this command adds another book to the
collection. It allocates a node, copies the data into it, and
links the node into the three trees ordered by author, subject,
and title. Note that you are required to put the *same* node
simultaneously into three tree structures. There will be class
discussion about what is involved in doing this.
Note that in the real world two books can have the same author,
or the same title, or the same subject. Your program must do
something reasonable when there is a "tie" between two keys.
To avoid some of the potential technical details, however, we
will assume that titles are unique.
If and when the insertion is sucessfully completed, the program
must print a message saying so to standard output. Include
some information about WHERE in the list the new indexCard got
inserted, for each key -- this will be good to know for
debugging purposes. For example, if the Baum book gets
inserted in the author list as the right child of a book by
Baker, it would be nice if the message said that. It would
give us immediate confirmation that the insertion was done
properly.
COMMAND FORM:
Delete <title>
SPECIFIC EXAMPLE:
Delete The Wizard of Oz
This command must cause a search for the named book. If the
book is found, the pointers must be updated so that the book is
now deleted from all three trees.
Note: You have to remove the node from three trees, one after
the other. This constraint introduces a subtle difficulty:
You can't use the "copy trick" described in our textbook to
simplify the case of deleting a node that has two children. Do
you see why?
We will discuss this issue in class.
An appropriate message must be printed when a successful
deletion is done.
If the book is not found, the procedure must leave the list and
pointers unchanged, and simply print an appropriate message to
the user.
COMMAND FORM:
List by <key>
SPECIFIC EXAMPLE:
List by author
This command must print out the contents of each indexCard in
the list, in order according to the indicated key. The key can
be either author, title, or subject. Use an attractive format.
If the list is empty, an appropriate message must be printed.
COMMAND FORM:
Quit
SPECIFIC EXAMPLE:
Quit
This command must cause the program to Halt. Print a brief
acknowledgement message before quitting -- like "Quit command
received ... exiting."
NOTE ON DESIGN:
The "right" way to do this program is to implement the list as
an abstract data type that gives you all the basic operations
you need for implementing the commands you must support. We
will discuss this in class.
Consider implementing the basic node data in this manner:
#include <string>
#include <iostream.h>
#define MAX_CARDS 50
#define NUM_PTRS 6
typedef struct
{
string title ;
string author ;
string subject ;
}
indexCardType ;
struct TreeNodeType ;
typedef TreeNodeType *ptrType ;
enum ptrNameType {leftAuthor, rightAuthor, leftTitle,
rightTitle, leftSubject, rightSubject} ;
typedef ptrType ptrArrayType[NUM_PTRS] ;
struct TreeNodeType
{
indexCardType Item ;
ptrArrayType pointerTo ;
} ;
int main()
{
TreeNodeType node ;
node.Item.title = "Hello World!" ;
node.pointerTo[leftSubject] = NULL ;
cout << node.Item.title << endl ;
if (node.pointerTo[leftSubject] == NULL)
cout << "The pointer is NULL." << endl ;
else cout << "The pointer is not NULL." << endl ;
return 0;
}
This is a pretty "nifty" way to do things. You can pass a
variable of type ptrNameType as a parameter to a function.
This can facilitate writing a single procedure to do all binary
search tree insertions, a single procedure to do all binary
search tree deletions, and so on.
The alternative of having three separate sets of functions for
the three trees is "definitely not the best" design choice.
The values of ptrNameType can be passed to a function to
specify which pair of pointers to use when searching and
re-linking. Furthermore the values of ptrNameType are array
indices that will give your function direct access to the
pointers that the function needs to use and change. See how
the pointer is accessed in the main program above? Your
program can do all retrievals, insertions and deletions with
similar code.
If you use this idea, I think it will make the program much
easier to design and build.
TESTING:
You will need to do some careful testing.
Test all the functions of the program.
Tests must demonstrate that your program works correctly when
it deletes in the no-child, one-child, and two-children cases.
In particular, you have to devise a test that shows your program
is not susceptible to the problem involving the "copy trick"
that I mentioned above.
In your test script, you need to print out all the books in all
three orders after each insertion and each deletion.
The test script will count heavily on this assignment, so do a
good job. Also make sure that the script is very easy for me
to read and understand (in my 79-column display).