Homework 11: The List ADT Revisited
Doubly Linked Implementation and Recursive Functions
Overview
In this homework, you will revise your List ADT implementation and enhance it by reimplementing it with a doubly linked implementation and by defining it as a template class. In addition, we will use the List implementation as the basis for writing recursive functions. Some of these will be realizations of the functions we developed in class, and then we will add a few more.
Attributes/Structure
- The primary data item/attributes of a List object is a finite length homogeneous collection of data items arranged in sequential fashion:
- It is homogenious -- the elements in the collection are all of the same type.
- It has a finite length (the number of elements).
- The elements are arranged sequentially:
- There is a first element and a last element
- Every element except the last has a unique successor
- Every element except the first has a unique predecessor
- The List object has the notion of the current element. The current element may be any of the set {first, second, ..., last, EOL}. Note that since the implementation is a double linked list, and we are keeping track of the tail as well as the head, there is no longer any need to maintain a "predecessor postion" in the implementation.
Operations
Note in the following description of the operations, I will use DT to abstractly represent the data type of the elements of the queue. In the template impementation of the List class, this will be the passed template type.
Constructor/Destructor
List ( )
Preconditions: None.
Postconditions: Creates an empty list capable of holding Item type data items. Current position is at EOL.List ( const List & orig )
Preconditions: None.
Postconditions: Creates a new list object that is a copy of the given orig list. Note that the new list shares no storage with the original list.~List ( )
Preconditions: None.
Postconditions: Destroys the list, cleaning up all resources associated with the object.Mutator(s)
void insert ( const DT & item )
Preconditions: None.
Postconditions: The item has been inserted by copying into the list. Location of the insert occurs before the current position. After an insert, the current position follows the inserted item.void insertEnd ( const DT & item )
Preconditions: None.
Postconditions: The item has been inserted by copying into the list. Location of the insert occurs at the end of the list. Current position is at EOL following the insert.void insertBefore ( const DT & item, const DT & successor)
Preconditions: Datatype DT must allow '==' equality checking between items.
Postconditions: The item has been inserted by copying into the list immediately preceeding the first occurence of the given successor item. If successor is not found, the list is unaffected. Current position after a successful insert is at the successor item.void remove ( )
Preconditions: Current position is not EOL.
Postconditions: The item at the current position is removed from the list. The current position becomes that of the item's successor, or EOL if the removed item was the last in the list.void clear ( )
Preconditions: None.
Postconditions: The list is empty and all resources have been returned to the system.void reverse ( )
Preconditions: None.
Postconditions: The list has been reversed in order (so a list with a b c would be rewritten as c b a). This should be accomplished by using the existing items in the list.void reset ( )
Preconditions: None.
Postconditions: Resets the current position to the first item in the list. If the list is empty, then the position is set to EOL.bool advance ( )
Preconditions: None.
Postconditions: Advances the current position to the next item in the list. Advancing from EOL leaves the current position at EOL. If the position following the advance is not EOL, the result of the function is TRUE, and if the position following the advance is EOL, the result of the function is FALSE.List& operator= ( const List & rhs )
Preconditions: None.
Postconditions: Previous list object resources have been returned to the system and the list has become a copy of the given List rhs. The current list is returned.Observers (Predicates and Accessor(s))
bool isEmpty ( ) const
Preconditions: None.
Postconditions: Return value is true if the list contains no items, and false otherwise.bool isFull ( ) const
Preconditions: None.
Postconditions: Returns false.DT getCurrent ( ) const
Preconditions: Current position is not EOL.
Postconditions: Return value is a copy of the item at the current position. The list is unaffected.int length ( ) const
Preconditions: None.
Postconditions: Returns the length of the list. The list is unaffected.void write ( ostream & os ) const
Preconditions: None.
Postconditions: The list has been output to the given ostream. The list is unaffected.void writeMirror ( ostream & os ) const
Preconditions: Objects of type DT can be output using stream insertion to the given ostream.
Postconditions: The data items in the list are output to the given ostream. The function outputs the items from beginning to end and then from end back to beginning. The list is unaffected.Assignment
Be sure and use the C++ Programming Style Guide and follow the conventions described there. Up to 30% of the grade for this homework will be based on following these conventions and practicing good documentation.
Your task is to (re)implement the List ADT using a double linked list implementation. You must use a template class definition so that we can easily define different types of list in the same program. You are also required to implement a non-member function that overloads the stream insertion operator for List objects. Please be sure that the stream insertion indicates element in the sequence is the beginning, end, and current position of the list.
The following functions should be designed using recursion: length(), write(), writeMirror(), insertEnd(), insertBefore(), and reverse().
You must create a test plan to thoroughly test all of your List operations, and demonstrate through use of a driver program that your operations perform correctly across the different tests of your test plan. Submit the execution of your test plan by cutting and pasting from your Terminal window into a text editor and saving the file with the name testoutput.txt. The driver should be general and allow interactive testing of all operations, so there should be one key operations interpreted by the driver program (+ for enqueue, - for dequeue, @ to show current beginning of queue, C for clear, D for display the entire queue, A to demonstrate the assignment overload in a meaningful way, etc.).
Please instantiate your template List at least as a List of chars.