/* a generic queue implemented using a linked list of nodes * @author Biagioni, Edoardo * @assignment lecture 14 * @date March 3, 2008 * @inspiration William Albritton's LinkedQueue.java, * href="http://www2.hawaii.edu/~walbritt/ics211/queueLinked/LinkedQueue.java * and LinkedList.java */ public class LinkedQueue<T> { /* only need to store a single pointer to the node at the back * of the queue. * The pointer is null if the queue is empty. * Also record the size of the queue. * Values are initialized correctly for an empty queue, so * no constructor is needed. */ protected Node<T> back = null; /* invariant: size is the number of nodes in the queue pointed to by back*/ protected int size = 0; /* accessor method */ public int size() { return size; } /* @param value to add to the end of the list * @return true, this method always succeeds */ public boolean offer(T value) { if (back == null) { // special case back = new Node<T>(value, null); back.setNext(back); // queue is a circular list } else { // new node points to the first node in the queue Node<T> newNode = new Node<T>(value, back.getNext()); // the old back of the queue points to the new node back.setNext(newNode); // the new node is now at the back of the queue back = newNode; } size++; return true; } /* @return and remove the value at the head of the queue */ public T poll() { if (back == null) { // special case return null; } else { // return the first node in the queue, which in our circular // linked list, is the node after the last node in the queue T result = back.getNext().getValue(); if (size == 1) { // special case: removing last node in queue back = null; } else { // remove the first node from the queue back.setNext(back.getNext().getNext()); } size--; return result; } } /* convert the queue to a printable string * @return a string representing the queue */ public String toString() { if (back == null) { return "" + null; } else { return toString(back.getNext() /* first node */ , size); } } /* convert "nodesLeft" nodes to a string beginning with "node" * @param node the start of the list to convert * @param nodesLeft the count of nodes to convert, 0 to end * @return a string representing the node values */ private String toString(Node<T> node, int nodesLeft) { if (nodesLeft == 0) { return ""; } else { return node.getValue() + " : " + toString(node.getNext(), nodesLeft - 1); } } /* unit test -- test all the methods in this class * @param ignored */ public static void main(String[] args) { /* create two empty queues, make sure they print out correctly */ LinkedQueue<String> q1 = new LinkedQueue<String>(); LinkedQueue<String> q2 = new LinkedQueue<String>(); System.out.println("1: q1 = '" + q1 + "', q2 = '" + q2 + "'"); System.out.println("q1.size() = " + q1.size() + ", q2.size() = " + q2.size()); /* remove an item from an empty queue */ if ((q1.poll() != null) || (q2.poll() != null)) { System.out.println("error: removed item from empty queue(s)"); } System.out.println("2: q1 = '" + q1 + "', q2 = '" + q2 + "'"); /* insert some items, keep checking */ if (! (q1.offer("hello"))) { System.out.println("error inserting hello into q1"); } if (! (q1.offer("world"))) { System.out.println("error inserting world into q1"); } if (! (q2.offer("foo"))) { System.out.println("error inserting foo into q2"); } if (! (q2.offer("bar"))) { System.out.println("error inserting bar into q2"); } if (! (q2.offer("baz"))) { System.out.println("error inserting baz into q2"); } System.out.println("3: q1 = '" + q1 + "', q2 = '" + q2 + "'"); System.out.println("q1.size() = " + q1.size() + ", q2.size() = " + q2.size()); /* remove some items from the queues */ if (! (q1.poll().equals("hello"))) { System.out.println("error removing hello from q1"); } if (! (q2.poll().equals("foo"))) { System.out.println("error removing foo from q2"); } if (! (q2.poll().equals("bar"))) { System.out.println("error removing bar from q2"); } if (! (q2.poll().equals("baz"))) { System.out.println("error removing baz from q2"); } System.out.println("4: q1 = '" + q1 + "', q2 = '" + q2 + "'"); System.out.println("q1.size() = " + q1.size() + ", q2.size() = " + q2.size()); } }