/* DequeViaArray.java ** An instance of this class represents a deque ("Double Ended QUEue"), ** which combines the capabilities of a stack and a queue. That is, in ** a deque, elements can be inserted at both the front and the rear, and ** likewise removed from both the front and the rear. Only the elements ** at the front and at the rear can be retrieved. ** ** A wrap-around array representation is employed. ** ** Authors: R. McCloskey and < STUDENTs' NAMES > ** Date: March 2019 */ public class DequeViaArray implements Deque { // instance variables // ------------------ private T[] contents; // holds the items occupying this deque private int numItems; // how many items occupy this deque private int frontLoc; // location in contents[] where front is stored // constructor // ----------- /* Initializes this deque to be empty and to have the specifed capacity. ** An attempt to place more items into this deque when it is filled to ** capacity will be ignored. */ public DequeViaArray(int capacity) { contents = (T[])(new Object[capacity]); numItems = 0; frontLoc = 0; } // observers // --------- /* Reports whether or not this deque is empty (i.e. has no elements in it). */ public boolean isEmpty() { return sizeOf() == 0; } /* Reports whether or not this deque is full, meaning that an attempt ** to insert an item may fail. */ public boolean isFull() { return sizeOf() == contents.length; } /* Reports how many items occupy this deque. */ public int sizeOf() { return numItems; } /* Returns (a reference to) the item at the front of this deque. ** pre: !isEmpty() */ public T frontOf() { return contents[frontLoc]; } /* Returns (a reference to) the item at the rear of this deque. ** pre: !isEmpty() */ public T rearOf() { return contents[rearLoc()]; } /* Returns a list of the (images of the) items in the deque, ** going from front to rear, enclosed in square brackets. */ public String toString() { StringBuilder result = new StringBuilder("[ "); int k = frontLoc; for (int i=0; i != numItems; i++) { result.append(contents[k] + " "); k = succLoc(k); } result.append(']'); return result.toString(); } // mutators // -------- /* Removes the item at the front of this deque. ** pre: !isEmpty() */ public void removeFront() { contents[frontLoc] = null; // to aid garbage collection frontLoc = succLoc(frontLoc); numItems--; } /* Removes the item at the rear of this deque. ** pre: !isEmpty() */ public void removeRear() { // STUB!! // (One assignment statement suffices, but to hasten // garbage collection you also could include statement(s) // having the effect of placing null into the location // of contents[] in which the rear item is stored.) } /* Inserts the specified item at the front of this deque. */ public void insertAtFront(T elem) { if (isFull()) { } // In case this deque is full, do nothing else { // STUB!! // Update 'frontLoc' appropriately, place new element // there, and update 'numItems'. } } /* Inserts the specified item at the rear of this deque. */ public void insertAtRear(T elem) { if (isFull()) { } // In case this deque is full, do nothing. else { contents[succLoc(rearLoc())] = elem; numItems++; } } // private utiliy methods // ---------------------- /* Returns the location, within contents[], at which the deque's ** rear element is stored. */ private int rearLoc() { // STUB!! // The correct value to return is a function of // 'frontLoc', 'numItems', and contents.length. return 0; } /* Returns the successor of k in the wraparound range (0..N), ** where N = contents.length ** Examples: Assume N = 10. ** Then the successor of 5 is 6 and the successor of 9 is 0. */ private int succLoc(int k) { // STUB!! return 0; } /* Returns the predecessor of k in the wraparound range (0..N), ** where N = contents.length ** Examples: Assume N = 10. ** Then the predecessor of 5 is 4 and the successor of 0 is 9. */ private int predLoc(int k) { // STUB!! return 0; } }