next up previous index
Next: Methods Up: Queues Previous: Queues   Index

Simple Implementation

Again we begin with a simple implementation of a queue of fixed maximum size, as shown in Figure 3.1.

Figure 3.1: A simple implementation of the queue.
public class SimpleQueue {

    private Object[] queue;
    private int size; // size of the queue
    private int top;  // for next insertion
    private int base; // for next removal

    public SimpleQueue(int capacity) {
        queue = new Object[capacity];
        size = top = base = 0; 
    }
  
    public boolean isEmpty() {
        return size == 0;
    }

    public boolean isFull() {
        return size == queue.length;
    }
  
    public void enqueue(Object item) {
        if (isFull()) {
            throw new RuntimeException("queue overflow");
        } else {
            queue[top++] = item;
            if (top == queue.length) {
                top = 0;
            }
            ++size;
        }
    }

    public Object dequeue() {
        if (isEmpty()) {
            throw new RuntimeException("queue underflow");
        } else {
            Object item = queue[base++];
            if (base == queue.length) {
                base = 0;
            }
            --size;
            return item; 
        }
    }
}

As with stacks there is a private array in which the queue items are stored. There are now two pointers top and base, as well as a variable size to record the number of items currently waiting in the queue. The following explains the roll of these three variables.

Items to be enqueued will be written in the array at queue[top]. Items to be dequeued will be read from queue[base]. After each write, top is incremented by one and after each read, base is incremented by one. The exception is when either would run off the end of the array. In that case it is reset to 0. This is the way a clock works. After 11 comes 12 = 0 and then 1 and so on.

You could think of top and base as two cars racing around a circuit. They begin level, but then top has an unfair advantage: base is allowed to draw level, but never to overtake. There is a restriction on top, however. It is never allowed to lap base, i.e. overtake one lap ahead.

The amount by which top is in the lead is given by the variable size which will always lie between 0 when the queue is empty, and queue.length when the queue is full. In simple terms size is equal to top-base modulo queue.length. However, that is not quite accurate. In the case top == base we cannot tell whether we have a full or an empty queue without some further information. Recording the number of items remaining to be processed in the queue is not the only way of supplying this information, but it is probably the simplest and most natural.



Subsections
next up previous index
Next: Methods Up: Queues Previous: Queues   Index
Peter Williams 2005-06-07