Queue
1.Introduction
Add the end of queue and remove elements from the beginning of the queue (First In First Out)
Enqueue: Adding a new element to the end of the queue
Dequeue: Removing an element from the beginning of a queue
Peek
Offer: Adding to a queue if space is available
2.The complexity
Enqueue, dequeue, isEmpty, isFull: O(1)
space complexity: O(N)
3.Where can stacks be used
Customer service hotline, calls are assigned to representatives in the order that they are received
Queueing jobs to be printed
Any order processing systems like in e-commerce websites or bank transaction systems
4.Implement a queue using two stacks
Forward stack
Use a forward stack used to push the enqueue elements
Enqueue operations are always performed on the forward stack
Enqueue requires moving all elements to the forward stack and pushing the last element in I.E. the top
Reverse stack
The reverse stack holds the elements in reverse order from the forward stack
Dequeue operations are always performed on the reverse stack
Dequeue requires moving all elements to the reverse track and popping the last element in I.E. the top
Performance and complexity
All enqueues and then dequeues ate O(1) - if only one of these operations are performed
O(m)
public class QueueBuiltWithTwoStacks<T> {
private Stack<T> forwardStack = new Stack();
private Stack<T> reverseStack = new Stack();
public QueueBuiltWithTwoStacks() {
}
public boolean isEmpty() {
return forwardStack.isEmpty() && forwardStack.isEmpty();
}
public boolean isFull() {
return forwardStack.isFull() || forwardStack.isFull();
}
public void enqueue(T data) throws Queue.QueueOverflowException {
if (isFull()) {
throw new QueueOverflowException();
}
try {
if (forwardStackStack.isEmpty()) {
while (!reverseStack.isEmpty()) {
forwardStack.push(reverseStack.pop());
}
}
forwardStack.push(data);
} catch(Stack.StackOverflowException | Stack.StackUnderflowException se) {
throw new Queue.QueueOverflowException
}
}
public T dequeue throws Queue.QueueUnderflowException {
if (isEmpty()) {
throw new QueueUnderflowException();
}
try {
if (reverseStack.isEmpty()) {
while (!forwardStack.isEmpty()) {
reverseStack.push(reverseStack.pop());
}
}
return reverseStack.push(data);
} catch(Stack.StackOverflowException | Stack.StackUnderflowException se) {
throw new Queue.QueueUnderflowException
}
}
}
5.The circular queue
public class Queue<T> {
private static final int SPECIAL_EMPTY_VALUE = -1;
private static int MAX_SIZE = 40;
private T[] elements;
private int headIndex = SPECIAL_EMPTY_VALUE;
private int tailIndex = SPECIAL_EMPTY_VALUE;
public class Queue<T>(Class<T> clazz) {
elements = (T[]) Array.newInstance(class, MAX_SIZE);
}
public boolean isEmpty() {
return headIndex == SPECIAL_EMPTY_VALUE;
}
public boolean isFull() {
int nextIndex = (tailIndex + 1) % elements.length;
return nextIndex == headIndex;
}
public void enqueue(T data) throws QueueOverflowException {
if (isFull()) {
throw new QueueOverflowException();
}
tailIndex = (tailIndex + 1) % elements.length;
elements[tailIndex] = data;
if (headIndex == SPECIAL_EMPTY_VALUE) {
headIndex = tailIndex;
}
}
public void dequeue(T data) throws QueueUnderflowException {
if (isFull()) {
throw new QueueUnderflowException();
}
T data = elements[headIndex];
if (headIndex == tailIndex) {
headIndex = SPECIAL_EMPTY_VALUE;
} else {
headIndex = (headIndex + 1) % elements.length;
}
return data;
}
}
Last updated