Queue is used to store and manage elements in a particular order. It operates on the First-In-First-Out (FIFO) principle, the element pushed first is to be popped from the queue. In this article, we will explore the various operations of a queue, how to implement queues, and some real-world applications of queues in data structures.
Some of the basic operations of a queue are:
There are various ways to implement queues, including:
#include <iostream>
using namespace std;
#define MAX 5
class Queue {
int arr[MAX];
int front, rear;
public:
Queue() {
front = -1;
rear = -1;
}
bool isEmpty() {
return front == -1;
}
bool isFull() {
return rear == MAX - 1;
}
void enqueue(int value) {
if (isFull()) {
cout << "Queue is full!" << endl;
} else {
if (front == -1)
front = 0;
rear++;
arr[rear] = value;
cout << "Enqueued: " << value << endl;
}
}
void dequeue() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
} else {
cout << "Dequeued: " << arr[front] << endl;
front++;
if (front > rear) {
front = rear = -1;
}
}
}
void display() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
} else {
cout << "Queue elements: ";
for (int i = front; i <= rear; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
}
};
int main() {
Queue q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(5);
q.display();
q.dequeue();
q.display();
return 0;
}
Output:
Enqueued: 1
Enqueued: 2
Enqueued: 5
Queue elements: 1 2 5
Dequeued: 1
Queue elements: 2 5
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;
};
class Queue {
Node* front;
Node* rear;
public:
Queue() {
front = rear = nullptr;
}
bool isEmpty() {
return front == nullptr;
}
void enqueue(int value) {
Node* temp = new Node();
temp->data = value;
temp->next = nullptr;
if (isEmpty()) {
front = rear = temp;
} else {
rear->next = temp;
rear = temp;
}
cout << "Enqueued: " << value << endl;
}
void dequeue() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
} else {
Node* temp = front;
cout << "Dequeued: " << front->data << endl;
front = front->next;
delete temp;
}
}
void display() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
} else {
Node* temp = front;
cout << "Queue elements: ";
while (temp != nullptr) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
}
};
int main() {
Queue q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(5);
q.display();
q.dequeue();
q.display();
return 0;
}
Output:
Enqueued: 1
Enqueued: 2
Enqueued: 5
Queue elements: 1 2 5
Dequeued: 1
Queue elements: 2 5
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;
};
class Queue {
Node* front;
Node* rear;
public:
Queue() {
front = rear = nullptr;
}
bool isEmpty() {
return front == nullptr;
}
void enqueue(int value) {
Node* temp = new Node();
temp->data = value;
temp->next = nullptr;
if (isEmpty()) {
front = rear = temp;
} else {
rear->next = temp;
rear = temp;
}
cout << "Enqueued: " << value << endl;
}
void dequeue() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
} else {
Node* temp = front;
cout << "Dequeued: " << front->data << endl;
front = front->next;
delete temp;
}
}
void display() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
} else {
Node* temp = front;
cout << "Queue elements: ";
while (temp != nullptr) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
}
};
int main() {
Queue q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(5);
q.display();
q.dequeue();
q.display();
return 0;
}
Output:
Enqueued: 1
Enqueued: 2
Enqueued: 5
Queue elements: 1 2 5
Dequeued: 1
Queue elements: 2 5
#include <iostream>
#include <stack>
using namespace std;
class Queue {
stack<int> s1, s2;
public:
void enqueue(int value) {
s1.push(value);
cout << "Enqueued: " << value << endl;
}
void dequeue() {
if (s1.empty() && s2.empty()) {
cout << "Queue is empty!" << endl;
} else {
if (s2.empty()) {
while (!s1.empty()) {
s2.push(s1.top());
s1.pop();
}
}
cout << "Dequeued: " << s2.top() << endl;
s2.pop();
}
}
void display() {
if (s1.empty() && s2.empty()) {
cout << "Queue is empty!" << endl;
} else {
cout << "Queue elements: ";
if (!s2.empty()) {
stack<int> temp = s2;
while (!temp.empty()) {
cout << temp.top() << " ";
temp.pop();
}
}
stack<int> temp = s1;
while (!temp.empty()) {
cout << temp.top() << " ";
temp.pop();
}
cout << endl;
}
}
};
int main() {
Queue q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(5);
q.display();
q.dequeue();
q.display();
return 0;
}
Output:
Enqueued: 1
Enqueued: 2
Enqueued: 5
Queue elements: 5 2 1
Dequeued: 1
Queue elements: 2 5
#include <iostream>
using namespace std;
struct Queue {
int front, rear, size;
int capacity;
int* array;
Queue(int cap) {
capacity = cap;
front = size = 0;
rear = capacity - 1;
array = new int[capacity];
}
bool isFull() {
return (size == capacity);
}
bool isEmpty() {
return (size == 0);
}
void enqueue(int item) {
if (isFull()) {
cout << "Queue is full! Cannot enqueue." << endl;
return;
}
rear = (rear + 1) % capacity;
array[rear] = item;
size++;
cout << "Enqueued: " << item << endl;
}
int dequeue() {
if (isEmpty()) {
cout << "Queue is empty! Cannot dequeue." << endl;
return -1;
}
int item = array[front];
front = (front + 1) % capacity;
size--;
return item;
}
int peek() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
return -1;
}
return array[front];
}
void display() {
if (isEmpty()) {
cout << "Queue is empty!" << endl;
return;
}
cout << "Queue: ";
for (int i = 0; i < size; i++) {
cout << array[(front + i) % capacity] << " ";
}
cout << endl;
}
};
int main() {
Queue q(5);
q.enqueue(1);
q.enqueue(2);
q.enqueue(5);
q.display();
cout << "Front element is: " << q.peek() << endl;
return 0;
}
Output:
Enqueued: 1
Enqueued: 2
Enqueued: 5
Queue: 1 2 5
Front element is: 1
Here are the applications of queues in data structures:
In conclusion, queues in data structures enable efficient management of elements in various real-world applications. The basic operations of a queue, including enqueue, dequeue, peek, and isEmpty, provide a simple way to handle tasks in a first-in, first-out (FIFO) manner. These operations are essential for ensuring the orderly processing of tasks and resource allocation in systems. By maintaining a well-structured queue, systems can achieve efficiency, and predictability in task execution, making queues indispensable in both computing and everyday applications.
A circular queue is a type of queue where the rear and front pointers circularly wrap around the way, effectively using all the available space without wasting it.
A queue follows the FIFO principle, meaning the first element added is the first one removed. A stack, on the other hand, follows the LIFO principle, where the last element added is the first one removed.