A queue is a container of objects that are inserted and removed based on FIFO (First-in First-out) principle.
In the queue, there are two major operations, enqueue and dequeue.
1. Enqueue means inserting a new item to the back of the queue.
2. Dequeue means removing the first item from the queue.
Just like Stack, Queue is also a data structure that is built on top of other data structures (array, ArrayList, or LinkedList). No matter what underlying structure it uses, we want to make sure that a queue implements the same following functionalities.
public interface QueueInterface<AnyType> {
void enqueue(AnyType item); // O(1)
AnyType dequeue(); // O(1)
AnyType peekFront(); // O(1)
boolean isEmpty(); // O(1)
}
Array-based implementation
We need some fields:
1. An "array elements" which has a fixed length.
2. Variable "back" that refers to the back of the queue.
3. Variable "front" that refers to the front of the queue.
4. Additionally, some others such as "nitems" variable to keep track of current number of items.
Every time a new item is added (enqueued), the "back" index should be increased.
And, when the front item is removed (dequeued), the "front" index should also be increased.
Circular Queue
When we need to do is to have "front" and "back" variables wrap around the array. The result is the circular queue.
Skeleton: ArrayQueue class
public class ArrayQueue<AnyType> implements QueueInterface<AnyType> {
private static final int DEFAULT_CAPACITY = 6;
private Object[] elements;
private int front; // front index
private int back; // back index
private int nItems; // current number of items
public ArrayQueue() {
elements = new Object[DEFAULT_CAPACITY];
front = 0;
back = -1;
nItems = 0;
}
// TODO Implements all of the core methods here
}
Enqueue
// Inserts a new item into the back of the queue
@Override
public void enqueue(AnyType item) {
if (nItems == elements.length) {
throw new RuntimeException("Queue is full");
}
back++;
int index = back % elements.length;
elements[index] = item;
nItems++;
}
Dequeue
// Returns and removes the item at the front
@Override
public AnyType dequeue() {
if (isEmpty()) {
throw new NoSuchElementException();
}
int index = front % elements.length;
AnyType result = (AnyType)elements[index];
elements[index] = null; // remove it
front++;
nItems--; // one less in the queue
return result;
}
Peek Front
// Returns the first item in the queue without removing it
@Override
public AnyType peekFront() {
if (isEmpty()) {
throw new NoSuchElementException();
}
return (AnyType)elements[front % elements.length];
}
isEmpty
@Override
public boolean isEmpty() {
return nItems == 0;
}
LinkedListQueue
LinkedList<Integer> theQueue = new LinkedList<Integer>();
// enqueue into the queue
theQueue.addLast(5);
// dequeue from the queue
theQueue.removeFirst();
Also there are other methods in LinkedList and ArrayDequeue such as offer(E e), pollFirst(), and pollLast(), etc.