| CS 261 | University of Puget Sound | Spring, 2020 |
|
Computer Science II
|
||
|
Abstract Data Types and their Implementations,
Some Basic Algorithms,
Object-oriented Problem Solving, and Efficiency |
||
Warning:
This course is under development.
Although the basic structure of this course is largely established,
nothing on this Web site should be considered official or even possibly
correct.
DO NOT MAKE PLANS BASED ON THE CONTENTS OF THIS SITE UNTIL JANUARY, 2020.
This laboratory exercise introduces the concept of the queue abstract data type and provides experience implementing this ADT.
After introductory material on queues as abstract data types, work on queue implementations proceeds in two parts:
Today's reading on queues describes a queue as an ADT that can store data and that has the following operations:
initializeQueue
Initializes an empty queue object.
isEmpty
Determine whether the queue is empty; return true if it is and
false if it is not.
isFull
Determine whether the queue is full; return true if it is and
false if it is not.
enqueue
Add a new element at the rear of a queue.
dequeue
Remove an element from the front of the queue and return it. (This
operation cannot be performed if the queue is empty.)
front
Return the element at the front of the queue (without removing it from the
queue). (Again, this operation cannot be performed if the queue is empty.)
Typical methods for a queue follow:
/* a constructor for an empty queue
*/
/* return whether the queue is empty
pre: queue is an initialized queue
post: returns true if queue is empty;
false otherwise
*/
public boolean isEmpty ()
/* return whether the queue is full
pre: queue is an initialized queue
post: returns true if an additional item
cannot be added to the queue;
false otherwise
*/
public boolean isFull ()
/* insert given item into back of the queue
pre: the specified queue is initialized
returns: null if queue is full
otherwise, reference to item added
*/
E enqueue (E item)
/* removes front item from queue referenced by parameter
pre: the specified queue is initialized
returns: null if queue is empty
otherwise, reference to the item removed
*/
E dequeue ()
Be sure you have read the reading on queues, particularly the reading on the implementation of queues by arrays, before continuing.
In this part of the lab, we will focus on arrays of generic type E. The relevant fields are:
public class Queue <E> {
protected first;
protected last;
protected count;
E queueArray [] ;
...
A constructor would initialize the queueArray to an
array of a specified size. (Pragmatically, the size might be a
constructor parameter.)
Additional implementation notes may be found in today's reading on Queues.
Write two implementations of a queue of strings by implementing these operations.
Use the queue operations within a main procedure to provide thorough testing of each operation.
Add to the queue ADT an additional procedure print
that displays each of the elements of the queue on a separate line
(without actually removing any of them from the queue).
An alternative approach for the dequeue procedure would add a parameter item to the list of parameters and change the return type to an int type. The idea is that the string would be returned as a parameter char * item and the procedure would return the length of the string item or -1 if the queue was empty. The relevant procedure signature might be:
int dequeue (stringQueue * queue, char ** item)
and this procedure would be called within the context:
char * frontItem; int returnValue; stringQueue myQueue; ... returnValue = dequeue (&myQueue, &frontItem)
Typically, the last records where new items will be added to a queue. However, at least two interpretations are possible:
In the diagram, note lastB = lastA + 1
In an array implementation of a queue, either interpretation can work without trouble, but the details are different:
Also, assuming the very first item will be placed in array element 0, the initializations of the index fields must be different.
As noted, either approach can work without trouble, but mixing the two interpretations will likely yield errors. Choosing an interpretation may be called specifying an invariant of the queue code. Throughout all queue operations, the interpretation of last (i.e., using lastA or lastB) never varies. Likely the code will use the simple field name last, but the programmer will need to have decided which approach is being used.
A similar two choices are possible for first