What Is a Queue?
A queue is a linear data structure that stores elements in a specific order and processes them according to the FIFO (First In, First Out) principle. The element that enters the queue first is normally the first element to be removed.
A simple real-world example is a line of people waiting at a service counter. The person who arrives first is generally served first, while newly arriving people join the end of the line. A queue data structure follows the same basic idea.
Queue order:
Front → [ 10 ] [ 20 ] [ 30 ] [ 40 ] ← Rear Remove → 10 Add → 50 After adding 50: Front → [ 20 ] [ 30 ] [ 40 ] [ 50 ] ← Rear
Understanding FIFO
FIFO stands for First In, First Out. It describes the order in which elements are processed. If several elements are added to a queue, they are removed in the same order in which they were inserted.
For example, if the values 10, 20, and 30 are inserted into a queue, the removal order will be
10, then 20, and finally 30.
| Operation | Queue | Result |
|---|---|---|
| Enqueue 10 | 10 | 10 enters first |
| Enqueue 20 | 10, 20 | 20 joins the rear |
| Enqueue 30 | 10, 20, 30 | 30 joins the rear |
| Dequeue | 20, 30 | 10 is removed first |
Front and Rear of a Queue
A queue normally has two important positions: the front and the rear. The front identifies the element that is next to be removed, while the rear identifies where a new element is added.
Queue
↓
Front → [ 15 ] [ 25 ] [ 35 ] [ 45 ] ← Rear
↑ ↑
Remove here Add here
Maintaining these two ends makes the queue concept different from structures where elements can be freely inserted or removed from arbitrary positions.
Basic Queue Operations
A queue provides a small set of core operations for adding, removing, and inspecting elements.
- Enqueue: Adds an element to the rear of the queue.
- Dequeue: Removes the element from the front of the queue.
- Peek: Returns the front element without removing it.
- IsEmpty: Determines whether the queue contains any elements.
- Size: Returns the number of elements currently stored.
Enqueue
Enqueue is the operation used to add a new element to the rear of a queue. Existing elements remain in their current order.
Queue: [10] [20] [30] Enqueue(40) Queue: [10] [20] [30] [40]
The new value is placed after the current last element. This preserves FIFO ordering.
Dequeue
Dequeue removes the element at the front of the queue. This is the operation that enforces the first-in, first-out behavior.
Queue: [10] [20] [30] Dequeue() Queue: [20] [30] Removed: 10
A dequeue operation on an empty queue requires special handling. Depending on the implementation, it may return a special value, throw an exception, or otherwise indicate that no element is available.
Queue vs Stack
Queues and stacks are both linear data structures, but they process elements in different orders. A queue follows FIFO, while a stack follows LIFO (Last In, First Out).
| Feature | Queue | Stack |
|---|---|---|
| Ordering | FIFO | LIFO |
| Insertion | Rear | Top |
| Removal | Front | Top |
| Typical use | Scheduling and processing in arrival order | Undo, backtracking, function calls |
How a Queue Can Be Implemented
A queue is an abstract data structure, so its behavior can be implemented using different underlying structures. Common implementations include arrays, linked lists, and language-provided queue collections.
When an array is used, the implementation must be designed carefully. Removing the first element from a basic array by shifting
every remaining element can take O(n) time. A more efficient implementation can maintain a front index so that
elements do not need to be shifted after every dequeue operation.
const queue = []; let front = 0; queue.push(10); queue.push(20); queue.push(30); const first = queue[front]; front++; console.log(first); // 10 console.log(queue[front]); // 20
Where Queues Are Used
Queues are useful whenever work needs to be processed in an ordered sequence, especially when the earliest waiting item should normally be handled first.
- Task scheduling: Processes waiting tasks in an ordered manner.
- Print systems: Manages documents waiting to be printed.
- Request processing: Stores requests waiting for server-side processing.
- Message systems: Holds messages until they can be consumed.
- Breadth-first search: Stores graph or tree nodes that need to be processed level by level.
- Event processing: Maintains events waiting for a system or component to handle them.
Queue in Breadth-First Search
One of the most important algorithmic uses of a queue is Breadth-First Search (BFS). BFS visits nodes level by level. A queue stores nodes that have been discovered but have not yet been processed.
Start ↓ Queue: [A] Remove A → add its neighbors Queue: [B, C] Remove B → add its unvisited neighbors Queue: [C, D, E]
Because nodes are processed in the order they are added, the FIFO behavior of a queue naturally supports level-order traversal.
Advantages of Queues
- Provides a clear FIFO processing model.
- Useful for managing waiting tasks and requests.
- Works naturally with breadth-first traversal algorithms.
- Can provide efficient insertion and removal when implemented correctly.
- Helps separate producers that generate work from consumers that process it.
Things to Consider
The word "queue" describes the behavior, not necessarily one specific implementation. The performance of a queue depends on how it is implemented.
For example, repeatedly removing the first element from a normal JavaScript array using shift() can require elements
to be reindexed or moved. For large queues, a head index, linked-list implementation, or dedicated queue structure can avoid
unnecessary work.
Queue Complexity
With an appropriate queue implementation, enqueue and dequeue operations are commonly designed to run in O(1) time.
The exact complexity depends on the underlying implementation.
| Operation | Typical Complexity | Purpose |
|---|---|---|
| Enqueue | O(1) | Add an element to the rear |
| Dequeue | O(1) | Remove the front element |
| Peek | O(1) | Read the front element |
| Search | O(n) | Find a specific element |
Queue Example in JavaScript
The following example uses an array together with a front index. This avoids repeatedly removing the first array element and demonstrates the basic FIFO behavior of a queue.
const queue = [];
let front = 0;
function enqueue(value) {
queue.push(value);
}
function dequeue() {
if (front >= queue.length) {
return null;
}
const value = queue[front];
front++;
return value;
}
function peek() {
return front < queue.length ? queue[front] : null;
}
enqueue("Task 1");
enqueue("Task 2");
enqueue("Task 3");
console.log(dequeue()); // Task 1
console.log(peek()); // Task 2
In a production implementation, additional logic can be used to periodically compact the array after many dequeue operations. The important concept here is that the front position moves forward while new elements continue to enter at the rear.
When Should You Use a Queue?
A queue is a natural choice when the order in which items arrive matters and earlier items should generally be processed before later items.
Common signals that a queue may be appropriate include:
- Items need to be processed in arrival order.
- Tasks are waiting for an available worker or resource.
- Requests need to be processed sequentially.
- An algorithm needs level-by-level traversal.
- There is a producer-consumer workflow.
Key Takeaways
- A queue is a linear data structure based on the FIFO principle.
- Elements are normally added at the rear and removed from the front.
- Enqueue adds an element, while dequeue removes an element.
- Peek reads the front element without removing it.
- Queues are widely used in scheduling, request processing, messaging, and BFS.
- The performance of queue operations depends on the implementation.
- An efficient queue can provide constant-time enqueue and dequeue operations.