Computer Science 173
Intermediate Computer Programming

Denison
CS173 Homework 6

Homework 6: The List ADT
Singly Linked List Implementation

Overview

In Homework 5, you created an implementation of the List ADT using an array to store the list data items. Although this approach is intuitive, it frequently is inefficient in storage usage and always inefficient in operation time. It wastes memory by allocating an array that is large enough to store what you estimate to be the maximum number of data items a list will ever hold. In most cases, the list is rarely this large and the extra memory simply goes unused. In addition, the insertion and deletion operations require shifting data items back and forth within the array, a very time consuming task.

In this homework, you will implement the List ADT using a singly linked list. This implementation allocates memory data item by data item as items are added to the list. Equally important, a linked list can support insertion and deletion operations simply by changing a few links.

Note that we are not changing the interface of the List ADT. A good interface definition should not have to change when we change the underlying implementation. If it does, then some aspect of the implementation has been reflected through the interface definition, and we have failed in our goal of information hiding. Thus the abstract properties of a List still hold:

  • 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

As we consider our linked list implementation, we see that, where the array implementation provided (by successive array elements) the sequential ordering of the list, we now use pointers explicitly linking list nodes together.

The next thing to consider is the data type of the data structures that are linked together. The list elements themselves have a common type abstracted by our Item class. It would be poor practice to incorporate the links within this Item type, so we need to create a new type that acts as a container for the Item and also has the links required by our implementation. In class, I called the type 'Element', but I will change to use the term from the book of 'Node'. A Node has two data members: an Item and a pointer to the next Node. For ease of manipulation by our List class, we will make these data members public. The Node class should simply have constructors in addition to the data members. We will discuss in class why we do not need a copy constructor nor an overload on the assignment operator.

Attributes

Structure

The key structure associated with the List ADT is the sequential notion of the collection referred to above -- with each data item except the first having a unique predecessor and each data item except the last having a unique successor.

Operations

Constructor/Destructor

List ( )

Preconditions: None.
Postconditions: Creates an empty list capable of holding Item type data items. Current position is at EOL.

~List ( )

Preconditions: None.
Postconditions: Destroys the list, cleaning up all resources associated with the object.

Mutator(s)

void insert ( const Item & item )

Preconditions: List is not full (i.e. the number of items currently in the list is less than MAX_ITEMS).
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 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 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.

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: Return value is true if the list contains MAX_ITEMS items, and false otherwise.

Item 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.

Assignment

Be sure and use the C++ Programming Style Guide and follow the conventions described there. Up to 35% of the grade for this homework will be based on following these conventions and practicing good documentation.

Your task is to implement the List ADT using a linked list, and in order to do so and to test, to implement the Item class, the Node class, and a driver program. To do this you will create a header file, named listlink.h which contains the class definition, and an implementation file, named listlink.cpp, which contains all of the definitions of the member functions corresponding to the operations described above. Likewise, you will create files item.h and item.cpp and node.h and node.cpp to wrap the basic type of items within a class, and Node to realize the structures being linked together in the List.

Use an array implementation for the underlying data structure of the List. You should use dynamic allocation at object creation time, and should return to free space the array at object destruction.

As before, the driver program should be general, and should allow operations including

  1. Creation of a list object to be used by the driver program
  2. Insertion of a user supplied item into the list
  3. Removal of the item at the current position
  4. Display the item at the current position
  5. Go to the beginning of the list
  6. Advance to the next position in the list
  7. Query if the list is empty
  8. Query if the list is full
  9. Display the entire list
  10. Empty the entire list

You will also detail a test plan that gives good coverage demonstrating that your implementation works and _then_ implement the test plan with a driver program named testList.cpp.

You should be able to use much of the infrastructure that you have already build in Homework 4, including the Item class and the driver program. To keep focused, the functionality of the List will be submitted in stages. In the first stage, you will implment the Node class and the basic List class operations of constructor, insert(), remove(), reset(), advance(), getCurrent(), isEmpty(), and isFull() as detailed above. This basic functionality will be due on Tuesday, October 10 in class. In the second stage, you will add the copy constructor for the List, the List destructor that deallocates all resources of the List and its constituent Node objects, as well as an overload of the assignment operator and an overload of stream insertion to clean up the way we do output. The Item class should also overload the stream insertion operator. These enhancements are due by midnight on Wednesday, October 11.