/** * Queues implemented with arrays using the "loop around to the first" method. * * @author Yvonne Palm * @author Samuel A. Rebelsky */ public class LoopedQueue implements Queue { // +--------------+--------------------------------------------- // | Design Notes | // +--------------+ /* We implement queues with arrays that can "wrap around". When we delete elements, we update our notion of first. When we add elements we put them at the end. If we reach the end, we move around to the first. We keep track of whether the array is full or empty (or anything in between) with the length field, which keeps track of the number of elements in the queue. */ // +--------+--------------------------------------------------- // | Fields | // +--------+ /** * The index of the first element of the queue. */ int first; /** * The index of the first empty space in the queue. */ int back; /** * The length of the queue. */ int length; /** * the array to be used. */ Object[] queue; // +--------------+--------------------------------------------- // | Constructors | // +--------------+ /** * Create a new, empty, queue. */ public LoopedQueue(){ this.queue = new Object[5]; // All null to begin with. this.length = 0; this.first = 0; this.back = 0; } // LoopedQueue() // +---------+-------------------------------------------------- // | Methods | // +---------+ /** * Determine if the queue is empty */ public boolean isEmpty() { return (0 == this.length); } // isEmpty() /** * Determine if the queue is full */ public boolean isFull() { return (this.queue.length == this.length); } //isFull() /** * Add something to the queue. */ public void add(Object thingToAdd){ if (this.isEmpty()) { this.first = 0; this.back = 0; } else if(this.isFull()) { // Build a bigger array with more space. Object[] newQueue = new Object[this.length * 2]; // Copy over the elements. for (int i = 0; i < this.length; i++) { newQueue[i] = this.queue[(this.first + i) % this.length]; } // Set that to our array this.queue = newQueue; this.first = 0; this.back = this.length; } // We're finally ready to add the thing. As long as we've made // sure that this.back is a valid index for the thing to add, // we're set. this.queue[this.back] = thingToAdd; // Update this.back this.back = this.back + 1; if (this.back == this.queue.length) { this.back = 0; } length++; }//add(Object) /** * Get the least recently added element. */ public Object get(){ // Sanity check if (this.isEmpty()) return null; // Remember the value Object returnValue = this.queue[this.first]; this.queue[this.first] = null; // Just for safety // Advance first to the next value ++this.first; if (this.first == this.queue.length) this.first = 0; // One fewer element --this.length; // That's it. return returnValue; }//get() /** * Get the length. */ public int length(){ return this.length; }//length() /** * Get the first element (non-destructively). */ public Object peek(){ return this.queue[first]; }//peek() /** * Convert to a string for ease of printing. */ public String toString(){ String result = "("; if(this.isEmpty()) { return "()"; } else { for(int i = 0; i < this.length; i++) { result += " " + this.queue[(i + this.first) % this.queue.length]; } //for } return result + ")"; } // toString() /** * Dump the thing to the screen (for debugging) */ public void dump() { System.out.println("First: " + this.first); System.out.println("Back: " + this.back); for (int i = 0; i < this.queue.length; i++) { System.out.println("A[" + i + "]: " + this.queue[i]); } // for } // dump() } // class LoopedQueue