When it comes to programming, data structures are like the unsung heroes working behind the scenes. They’re the reason we can organize, manage, and process data efficiently. Among all the data structures out there, queues stand out because of how natural and practical they feel.
Think about waiting in line at a coffee shop. The first person in line is the first person served. That’s exactly how queues work in programming — the First-In-First-Out (FIFO) rule. Whether it’s managing background tasks, scheduling processes, or running algorithms like breadth-first search, queues are everywhere once you know where to look.
In this post, let’s explore what makes queues so useful — from their basic operations to their variations and real-world use cases.
What Exactly Is a Queue?
At its core, a queue is a simple structure with just two main operations:
-
Enqueue → Add an item to the back of the line.
-
Dequeue → Remove (and return) the item at the front of the line.
That’s it. No cutting in line, no skipping ahead. The one that’s been waiting the longest always gets served first.
Queues can be built using arrays or linked lists. Both work, but each comes with its own trade-offs — arrays are simple and fast but fixed in size, while linked lists are more flexible and can grow as needed.
Why Are Queues So Useful?
-
FIFO makes sense in real life
The first one in is the first one out. Perfect for processes that need to happen in order, like handling requests or tasks. -
Super efficient operations
Enqueue and dequeue take constant time — O(1) — no matter how big your queue gets. -
Great for task management
Operating systems, job schedulers, and even web servers rely on queues to keep things fair and organized. -
Essential for algorithms
If you’ve ever worked with graphs, you’ve probably used a queue for breadth-first search (BFS). Without it, BFS simply wouldn’t work.
The Basic Operations
-
Enqueue → Add an element at the back.
-
Dequeue → Remove the front element.
-
Peek → Look at the front without removing it.
-
Size / Empty Check → Find out how many elements are inside or whether the queue is empty.
Simple but powerful.
Different Types of Queues
-
Array-based Queue
Uses a fixed-size array. Super fast, but you need to know the maximum size in advance. -
Linked List-based Queue
Uses nodes that can grow dynamically. No size limit, but a little more memory overhead.
Real-World Applications of Queues
-
Task Scheduling
Operating systems use job queues. Web apps use task queues. Everything waits its turn. -
Print Spooling
Remember waiting for your document to print? That’s a queue in action. -
Message Queues
Modern apps (think RabbitMQ, Kafka, SQS) rely on queues for communication between services. -
Traffic Management
Even cars waiting at a red light are basically in a queue — first in line moves first when the light turns green.
Queue Implementations in PHP and JavaScript
Now that we know what queues are and why they’re useful, let’s look at how to actually implement them in code. We’ll try it out in both PHP and JavaScript, using two different approaches: arrays and linked lists.
PHP: Array-Based Queue
Let’s start simple. An array-based queue is just a wrapper around a plain old PHP array. We’ll keep track of the front and rear of the line, as well as the current size.
<?php
class ArrayQueue {
private $queue;
private $front;
private $rear;
private $size;
public function __construct() {
$this->queue = [];
$this->front = 0;
$this->rear = 0;
$this->size = 0;
}
// Enqueue operation
public function enqueue($element) {
$this->queue[$this->rear++] = $element;
$this->size++;
}
// Dequeue operation
public function dequeue() {
if ($this->isEmpty()) {
return null;
}
$element = $this->queue[$this->front++];
$this->size--;
return $element;
}
// Peek operation
public function peek() {
return $this->isEmpty() ? null : $this->queue[$this->front];
}
// Check if the queue is empty
public function isEmpty() {
return $this->size === 0;
}
// Get the size of the queue
public function getSize() {
return $this->size;
}
}
// Example usage
$queue = new ArrayQueue();
$queue->enqueue(10);
$queue->enqueue(20);
$queue->enqueue(30);
echo "Peek: " . $queue->peek() . "\n"; // Peek: 10
echo "Dequeue: " . $queue->dequeue() . "\n"; // Dequeue: 10
echo "Size: " . $queue->getSize() . "\n"; // Size: 2
Here, enqueueing just pushes elements to the back, and dequeueing pops them off the front. Simple, fast, and clean — but since arrays in PHP are fixed in how they grow, this isn’t the most memory-efficient solution for very large queues.
PHP: Linked List-Based Queue
What if we don’t want to worry about fixed sizes? That’s where linked lists come in. Instead of using a rigid array, each element is stored in a node that points to the next one.
<?php
class Node {
public $data;
public $next;
public function __construct($data) {
$this->data = $data;
$this->next = null;
}
}
class LinkedListQueue {
private $front;
private $rear;
private $size;
public function __construct() {
$this->front = null;
$this->rear = null;
$this->size = 0;
}
// Enqueue operation
public function enqueue($element) {
$newNode = new Node($element);
if ($this->rear === null) {
$this->front = $this->rear = $newNode;
} else {
$this->rear->next = $newNode;
$this->rear = $newNode;
}
$this->size++;
}
// Dequeue operation
public function dequeue() {
if ($this->isEmpty()) {
return null;
}
$temp = $this->front;
$this->front = $this->front->next;
if ($this->front === null) {
$this->rear = null;
}
$this->size--;
return $temp->data;
}
// Peek operation
public function peek() {
return $this->isEmpty() ? null : $this->front->data;
}
// Check if the queue is empty
public function isEmpty() {
return $this->front === null;
}
// Get the size of the queue
public function getSize() {
return $this->size;
}
}
// Example usage
$queue = new LinkedListQueue();
$queue->enqueue(100);
$queue->enqueue(200);
$queue->enqueue(300);
echo "Peek: " . $queue->peek() . "\n"; // Peek: 100
echo "Dequeue: " . $queue->dequeue() . "\n"; // Dequeue: 100
echo "Size: " . $queue->getSize() . "\n"; // Size: 2
The linked list queue is more flexible — it can grow and shrink dynamically. No wasted memory, no fixed limits.
JavaScript: Array-Based Queue
Now let’s switch over to JavaScript. The logic is the same, but the syntax is a little cleaner.
class ArrayQueue {
constructor() {
this.queue = [];
this.front = 0;
}
// Enqueue operation
enqueue(element) {
this.queue.push(element);
}
// Dequeue operation
dequeue() {
if (this.isEmpty()) {
return null;
}
return this.queue[this.front++];
}
// Peek operation
peek() {
return this.isEmpty() ? null : this.queue[this.front];
}
// Check if the queue is empty
isEmpty() {
return this.front >= this.queue.length;
}
// Get the size of the queue
getSize() {
return this.queue.length - this.front;
}
}
// Example usage
const queue = new ArrayQueue();
queue.enqueue(5);
queue.enqueue(10);
queue.enqueue(15);
console.log("Peek:", queue.peek()); // Peek: 5
console.log("Dequeue:", queue.dequeue()); // Dequeue: 5
console.log("Size:", queue.getSize()); // Size: 2
This works exactly like the PHP version, just with cleaner array handling.
JavaScript: Linked List-Based Queue
Finally, here’s a linked list queue in JavaScript:
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
class LinkedListQueue {
constructor() {
this.front = null;
this.rear = null;
this.size = 0;
}
// Enqueue operation
enqueue(element) {
const newNode = new Node(element);
if (this.rear === null) {
this.front = this.rear = newNode;
} else {
this.rear.next = newNode;
this.rear = newNode;
}
this.size++;
}
// Dequeue operation
dequeue() {
if (this.isEmpty()) {
return null;
}
const temp = this.front;
this.front = this.front.next;
if (this.front === null) {
this.rear = null;
}
this.size--;
return temp.data;
}
// Peek operation
peek() {
return this.isEmpty() ? null : this.front.data;
}
// Check if the queue is empty
isEmpty() {
return this.front === null;
}
// Get the size of the queue
getSize() {
return this.size;
}
}
// Example usage
const queue = new LinkedListQueue();
queue.enqueue(50);
queue.enqueue(100);
queue.enqueue(150);
console.log("Peek:", queue.peek()); // Peek: 50
console.log("Dequeue:", queue.dequeue()); // Dequeue: 50
console.log("Size:", queue.getSize()); // Size: 2
Wrapping It All Up
Queues might look simple, but their usefulness is huge. Whether you’re working with arrays for quick and easy implementations, or linked lists for flexibility, queues give you a clean way to manage tasks in order.
They power task scheduling, printing systems, message queues, and even traffic control algorithms. Mastering them means you’re not just learning a data structure — you’re learning a pattern that shows up everywhere in programming and in real life.
Leave a Reply