Assignment 4
Due Thurs. 2/26/98
In the lecture we have discussed various linked list models.
Example files for some of these are in
/cs/cs60/ht/examples,
including:
- StringList.java
- open list of strings
- ClosedStringList.java
- list which can be treated as open or closed, with the closed part implementing the Stack abstraction
- StringListStack.java
- closed list implementing the Stack abstraction only
Whereas ClosedStringList.java contains all of the capabilities of the other two files, StringListStack.java removes the open list parts so that you can see the closed list part in pure form. Also in the examples directory are Stack.java and Queue.java which implement stacks and queues using arrays. These show the behaviors of these respective abstractions.
As we have mentioned in the lecture, a stack is a container in which the removal order of items is the reverse of the insertion order (LIFO or last-in-first-out). We also said that a queue is a container in which the removal order is the same as the insertion order (FIFO or first-in-first-out).
The purpose of this assignment is to implement a queue using a linked list. This will give you first-hand experience in working with objects and references to build linked structures. Toward this end, it is advised that you start from scratch rather than co-opting code in the directory. You may still look at that code as a guide.
The external characteristics of your queue are defined as
follows:
class StringListQueue { StringListQueue() // constructor void enqueue(String s) // insert S into this queue String dequeue() // remove the oldest string from this queue // and return it boolean isEmpty() // indicate whether the queue is empty or not }
A required internal characteristic is that your implementation should involve no unnecessary copying or reversals of the linked list. This probably means that you will need two pointers to list cells in the queue class, rather than one as in the case of the stack. One pointer points to the first cell and the other to the last.
The way in which these two pointers are used may be counter-intuitive at first. The first thing in the list is the cell containing the oldest element. The last thing in the list is the cell containing the youngest element. It is difficult to make this work if you don't observe the sense of these two pointers as mentioned.
The following diagrams show how a Queue would work:
A Queue with four elements
The Queue above after dequeue(); item a is returned.
The Queue above after enqueue(e).
The empty Queue
Don't create a doubly-linked list as this problem; it is totally unnecessary and creates additional complications which you don't need.
Here is a test program:
public static void main(String arg[]) { StringListQueue Q = new StringListQueue(); Q.enqueue("alpha"); Q.enqueue("beta"); Q.enqueue("gamma"); System.out.println("Q = " + Q); while( !Q.isEmpty() ) { System.out.println("Q.dequeue() = " + Q.dequeue()); System.out.println("Q = " + Q); } Q.enqueue("delta"); Q.enqueue("epsilon"); Q.enqueue("zeta"); Q.enqueue("eta"); System.out.println("Q = " + Q); while( !Q.isEmpty() ) { System.out.println("Q.dequeue() = " + Q.dequeue()); System.out.println("Q = " + Q); } }
and the corresponding output:
Q = (alpha beta gamma) Q.dequeue() = alpha Q = (beta gamma) Q.dequeue() = beta Q = (gamma) Q.dequeue() = gamma Q = () Q = (delta epsilon zeta eta) Q.dequeue() = delta Q = (epsilon zeta eta) Q.dequeue() = epsilon Q = (zeta eta) Q.dequeue() = zeta Q = (eta) Q.dequeue() = eta Q = ()