A QUEUE, or Queue, is a collection of elements that is used to organize and manipulate elements in a specific order.
Queues are also called FIFO structures (First-In, First-Out), because they follow the principle that the first element to be inserted (First-In) is the first one to be removed (First-Out).
Each time a new element is inserted into the QUEUE, it is placed at the back. When an element is removed, the one at the front is taken.
This is achieved through two main operations:
- Enqueue: Adds an element to the end of the queue.
- Dequeue: Removes and returns the element from the front of the queue.
Internally, a QUEUE can be implemented using a simple Array or a linked list, or a ring buffer, among other options.
In addition to these basic operations, other operations can also be performed on a QUEUE, such as checking if it is empty or accessing the front element without removing it.
Properties
Property | Queue |
---|---|
Frequency of use | 🔻🔻 |
Is mutable | ✔️ |
Is ordered | ✔️ |
Is indexable | ❌ |
Allows duplicates | ✔️ |
When to use a Queue
It makes sense to use a QUEUE in processes that involve waits and where it is logical that those who have been waiting the longest should be served first.
A queue resembles a line of people waiting for their turn in a service, for example, to enter the cinema. It is reasonable that the person who arrived first, has been waiting longer, and should be the first to be attended.
On a computer, it makes sense, for example, in the print queue. The documents waiting to be printed on the printer should be attended to in the order they were received.
There are many more examples. Almost whenever we have to address issues related to waiting for processes, or communications, we will likely have a queue-type structure.
Queue Example in Different Programming Languages
Below are examples of how to implement a queue in different programming languages:
C# has a native Queue called Queue
. So we just need to use it like this.
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
Queue<int> queue = new Queue<int>();
queue.Enqueue(5);
queue.Enqueue(10);
queue.Enqueue(15);
int frontElement = queue.Dequeue(); // Returns 5
Console.WriteLine(frontElement);
}
}
C++ also has a native Queue called queue<T>
, which we can use directly,
#include <iostream>
#include <queue>
using namespace std;
int main()
{
queue<int> queue;
queue.push(5);
queue.push(10);
queue.push(15);
int frontElement = queue.front(); // Returns 5
queue.pop();
cout << frontElement << endl;
return 0;
}
In contrast, JavaScript does not have a native Queue. So we can either look for an existing one in a library or implement it ourselves like this,
class Queue {
constructor() {
this.queue = [];
}
enqueue(element) {
this.queue.push(element);
}
dequeue() {
return this.queue.shift();
}
peek() {
return this.queue[0];
}
isEmpty() {
return this.queue.length === 0;
}
}
const queue = new Queue();
queue.enqueue(5);
queue.enqueue(10);
queue.enqueue(15);
const frontElement = queue.dequeue(); // Returns 5
console.log(frontElement);
Python has a native Queue called deque
, which we can use like this,
from collections import deque
queue = deque()
queue.append(5)
queue.append(10)
queue.append(15)
front_element = queue.popleft() # Returns 5
print(front_element)
The previous examples show how to create a queue using the data structures provided by each programming language. Insertion, deletion, and access to the front element of the queue are performed.
Efficiency
The efficiency of a QUEUE will depend on how it has been implemented internally (but, let’s consider it has been implemented “well”).
In this case, reading and removing elements from a queue are done in constant time O(1)
, as the first element of the queue is accessed.
Insertion in a queue is also efficient, as it is added to the end of the queue in constant time O(1)
.
Operation | Queue |
---|---|
Sequential access | ⚫ |
Random access | ⚫ |
Add to front | ⚫ |
Remove from front | 🟢 |
Add to end | 🟢 |
Remove from end | ⚫ |
Random insertion | ⚫ |
Random removal | ⚫ |
Search | ⚫ |
The rest of the operations do not make sense as you can only access the element at the top of the queue. You cannot access elements in intermediate positions without popping all the elements above.