/** An instance implements a queue of bounded size in an array */
public class ArrayQueue<E> {
    /* The n elements of the queue are in b[h], b[(h+1) % N], ... b[(h+n-1) % N]
     *    where N is b.length
     * invariant: all of the other entries of b are null
     * invariant: 0 <= h < b.length
     * invariant: 0 <= n <= b.length
     */
    E[] b;
    int n;
    int h;

    /** Constructor: a queue of maximum size n. */
    public ArrayQueue(int n) {
        this.b = (E[])new Object[n];
        this.n = 0;
        this.h = 0;
    }

    /** Return the size of the queue. */
    public int size() {
        return n;
    }

    /** = "queue is empty */
    public boolean isEmpty() {
        return n == 0;
    }

    /** = "queue is full */
    public boolean isFull() {
        return n == b.length;
    }

    /** Add e to the queue.
     *  @throws RuntimeException if the queue is full
     */
    public void put(E e) throws RuntimeException {
        if (isFull())
            throw new RuntimeException("queue full");
        b[(h+n) % b.length]= e;
        n= n+1;
    }

    /** Return the first element of the queue.
     *  @throws RuntimeException if the queue is empty
     */
    public E peek() throws RuntimeException {
        if (isEmpty())
            throw new RuntimeException("queue empty");
        return b[h];
    }

    /** Take the head of the queue off the queue and return it.
     *  @throws RuntimeException if the queue is empty
     */
    public E get() throws RuntimeException {
        if (isEmpty())
            throw new RuntimeException("queue empty");
        E e= b[h];
        h= (h+1) % b.length;
        n= n-1;
        return e;
    }

}
