๐ Unlocking the Magic of Queues: A Journey into Implementation and Concepts
Hello, fellow learners and coding enthusiasts! ๐ Today, we're diving into the captivating world of queues, a data structure that's as fascinating as it is essential. I'll be your guide on this quest as we explore the implementation, techniques, and key concepts that make queues so intriguing.
The Wonders of Queues ๐ฉ
Think of a queue as a line of people waiting to buy tickets for their favorite movie. The first in line gets their ticket first. That's the essence of a queue: "First-In-First-Out" (FIFO). In simple terms, the first item added to a queue is the first to be removed. Let's unlock the magic together.
Code in C/C++
#include<stdio.h>
#define SIZE 5
//Basic value initialization
int queue[SIZE], front = -1, rear = -1;
void Enqueue(int val){
if(rear == SIZE-1)
printf("Encountered Overflow Condition\n");
else{
//When adding initial element
if(front == -1)
front = 0;
rear++;
queue[rear] = val;
printf("%d was enqueued\n",val);
}
}
void Dequeue(){
if(front == -1)
printf("Underflow condition\n");
else{
printf("Dequeued : %d\n", queue[front]);
front++;
//resetting the queue when last item is Dequeued
if(front > rear)
front = rear = -1;
}
}
void display(){
if(rear == -1)
printf("\nQueue is empty");
else{
int i;
printf("\nNow, we are printing the Queue :");
for(i=front; i<=rear; i++)
printf("%d ",queue[i]);
}
}
int main()
{
Enqueue(10);
Enqueue(20);
Enqueue(30);
Enqueue(40);
Dequeue();
Dequeue();
display();
return 0;
}
Code in C/C++:
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
// creating a structure to hold the queue
struct myQueue
{
int front, rear;
unsigned size;
//here we have created a pointer which will point to memory of array
//created later in createQueue function
int* array;
};
// initialise the queue
struct myQueue* createQueue(unsigned size)
{
struct myQueue* queue = (struct myQueue*) malloc(sizeof(struct myQueue));
queue->size = size;
queue->front = -1;
queue->rear = -1;
//Memory is created for the array
queue->array = (int*) malloc(queue->size * sizeof(int));
return queue;
}
// Will return true if queue size has reached capacity
int isFull(struct myQueue* queue)
{
if(queue->rear == queue->size -1)
printf("Overflow condition\n");
return (queue->rear == queue->size -1);
}
// Will return true if the queue is empty
int isEmpty(struct myQueue* queue)
{
if(queue->front == -1)
printf("Underflow Condition\n");
return (queue->front == -1);
}
// function to Enqueue in the queue and change relevant values
void enqueue(struct myQueue* queue, int item)
{
if (isFull(queue))
return;
if(queue->front == -1)
queue->front = 0;
queue->rear++;
queue->array[queue->rear] = item;
printf("%d added to the queue\n", item);
}
// Function is deuque from queue and change relevant values
void dequeue(struct myQueue* queue)
{
if (isEmpty(queue))
return;
int item = queue->array[queue->front];
queue->front++;
//resetting the queue when last item is Dequeued
if(queue->front > queue->rear)
queue->front = queue->rear = -1;
printf("%d dequeued from queue\n", item);
}
//function to display the queue
void display(struct myQueue* queue)
{
if(queue->rear == -1)
printf("\nQueue was Empty!!!");
else{
int i;
printf("\nQueue :\n");
for(i=queue->front; i<=queue->rear; i++)
printf("%d ",queue->array[i]);
}
}
// Main function
int main()
{
struct myQueue* queue = createQueue(5);
enqueue(queue, 10);
enqueue(queue, 20);
enqueue(queue, 30);
enqueue(queue, 40);
dequeue(queue);
dequeue(queue);
display(queue);
return 0;
}
Code in C/C++ (removing the Limitation)
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
// Basic struct for queue
struct Queue
{
int front, rear, currSize;
unsigned maxCapacity;
// we are storing string in integer array, this will not give error
// as values will be stored in ASCII and returned in ASCII thus, returned as string again
int* array;
};
// Here we initialize queue and init. Current size of queue to 0
struct Queue* createQueue(unsigned maxCapacity)
{
struct Queue* queue = (struct Queue*) malloc(sizeof(struct Queue));
queue->maxCapacity = maxCapacity;
queue->front = queue->currSize = 0;
queue->rear = maxCapacity - 1; // This is important, see the enqueue
queue->array = (int*) malloc(queue->maxCapacity * sizeof(int));
return queue;
}
// Will return true if queue Current size has reached maxCapacity
int isFull(struct Queue* queue)
{
if(queue->currSize == queue->maxCapacity)
printf("Can't insert as queue is full\n");
return (queue->currSize == queue->maxCapacity);
}
// Will return true if queue Current size is 0
int isEmpty(struct Queue* queue)
{
if(queue->currSize == 0)
printf("Can't deuque as queue is empty\n");
return (queue->currSize == 0);
}
// Here we add new item to queue and change rear and Current size
void enqueue(struct Queue* queue, int item)
{
if (isFull(queue))
return;
//Bcz, queue->rear is set up to maxCapacity adding + 1
//and % maxCapacity will set rear to start of queue
//enqueue happens at the rear value always so to maintain First in first out
queue->rear = (queue->rear + 1)%queue->maxCapacity;
queue->array[queue->rear] = item;
queue->currSize = queue->currSize + 1;
printf("%d added to the queue at array pos:%d\n", item,queue->rear);
}
// Here we remove or dequeue from queue and
//also change the front value and Current size of queue
void dequeue(struct Queue* queue)
{
if (isEmpty(queue))
return;
int item = queue->array[queue->front];
queue->front = (queue->front + 1)%queue->maxCapacity;
queue->currSize = queue->currSize - 1;
printf("\n%d dequeued from queue, new front is at pos:%d\n", item,queue->front);
}
void display(struct Queue* queue)
{
if(queue->currSize == 0)
printf("\nQueue was Empty!!!");
else{
int i=queue->front, j;
printf("\nQueue :\n");
for(j=0; j<queue->currSize; j++)
printf("%d ",queue->array[(i+j)%queue->maxCapacity]);
}
}
// Main function to run queue program
int main()
{
struct Queue* queue = createQueue(5);
enqueue(queue,10);
enqueue(queue,20);
enqueue(queue,30);
enqueue(queue,40);
dequeue(queue);
dequeue(queue);
enqueue(queue,50);
enqueue(queue,60);
display(queue);
return 0;
}
Code in C++ (Class Implementation with Private Variables)
#include <bits/stdc++.h>
using namespace std;
// Basic struct for queue
class Queue
{
private:
int front, rear, currSize;
unsigned maxCapacity;
int* array;
public:
Queue(int size){
maxCapacity = size;
front = 0;
currSize = 0;
rear = maxCapacity - 1;
array = new int [maxCapacity];
}
void enqueue(int x);
void dequeue();
bool isEmpty();
bool isFull();
void display();
};
// Will return true if queue Current size has reached maxCapacity
bool Queue::isFull()
{
if(currSize == maxCapacity)
cout << "Can't insert as queue is full\n";
return (currSize == maxCapacity);
}
// Will return true if queue Current size is 0
bool Queue::isEmpty()
{
if(currSize == 0)
cout << "Can't deque as queue is empty\n";
return (currSize == 0);
}
// Here we add new item to queue and change rear and Current size
void Queue::enqueue(int item)
{
if (isFull())
return;
//Bcz, rear is set up to maxCapacity adding + 1
//and % maxCapacity will set rear to start of queue
//enqueue happens at the rear value always so to maintain First in first out
rear = (rear + 1)%maxCapacity;
array[rear] = item;
currSize = currSize + 1;
cout << item << " added to the queue at array pos:" << rear << endl;
}
// Here we remove or dequeue from queue and
//also change the front value and Current size of queue
void Queue::dequeue()
{
if (isEmpty())
return;
int item = array[front];
front = (front + 1)%maxCapacity;
currSize = currSize - 1;
cout << item << " dequeued from queue, new front is at pos:" << front << endl;
}
void Queue::display()
{
if(currSize == 0)
cout << "\nQueue was Empty!!!";
else{
int i,j;
cout <<"\nQueue :\n";
for(i=front,j=0; j<currSize; j++)
cout << array[(i+j) % maxCapacity] << " ";
}
}
// Main function to run queue program
int main()
{
Queue queue = Queue(5);
queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
queue.enqueue(40);
cout << endl;
queue.dequeue();
queue.dequeue();
cout << endl;
queue.enqueue(50);
queue.enqueue(60);
queue.display();
return 0;
}
Code in C++ (Class Implementation with Public Variables)
#include <bits/stdc++.h>
using namespace std;
// A structure to represent a queue
class Queue {
public:
int front, rear, size;
unsigned capacity;
int* array;
};
Queue* createQueue(unsigned capacity)
{
Queue* queue = new Queue();
queue->capacity = capacity;
queue->front = queue->size = 0;
queue->rear = capacity - 1;
queue->array = new int[queue->capacity];
return queue;
}
bool isFull(Queue* queue)
{
return (queue->size == queue->capacity);
}
bool isEmpty(Queue* queue)
{
return (queue->size == 0);
}
void enqueue(Queue* queue, int item)
{
if (isFull(queue))
return;
queue->rear = (queue->rear + 1)
% queue->capacity;
queue->array[queue->rear] = item;
queue->size = queue->size + 1;
cout << item << " is enqueued to Queue\n";
}
int dequeue(Queue* queue)
{
if (isEmpty(queue))
return INT_MIN;
int item = queue->array[queue->front];
queue->front = (queue->front + 1)
% queue->capacity;
queue->size = queue->size - 1;
return item;
}
int front(Queue* queue)
{
if (isEmpty(queue))
return INT_MIN;
return queue->array[queue->front];
}
int rear(Queue* queue)
{
if (isEmpty(queue))
return INT_MIN;
return queue->array[queue->rear];
}
// Driver code
int main()
{
Queue* queue = createQueue(5);
enqueue(queue, 10);
enqueue(queue, 20);
enqueue(queue, 30);
enqueue(queue, 40);
cout << "\n" << dequeue(queue)
<< " dequeued from Queue\n"<< endl;
cout << "Front: "
<< front(queue) << endl;
cout << "Rear: "
<< rear(queue) << endl;
return 0;
}
C++ STL Implementation of Queues
#include <iostream>
#include <queue>
using namespace std;
int main(){
queue <int> q;
q.push(10); // void type
q.push(20);
q.push(30);
q.push(40);
q.push(50);
cout << "Size: " << q.size() << endl;
cout << "Front,Rear: " << q.front() << "," << q.back() << endl;
q.pop(); // void type
cout << "Front,Rear: " << q.front() << "," << q.back() << endl;
queue <int> q2 (q);
cout << "Size: " << q2.size() << endl;
cout << "\nQueue: ";
while(!q.empty())
{
cout << q.front() << " ";
q.pop();
}
return 0;
}
Code in C:
#include <stdio.h>
#include <stdlib.h>
struct Queue
{
int front, rear, currSize;
unsigned maxSize;
int* a;
};
struct Queue* createQueue(unsigned maxSize)
{
struct Queue* queue = (struct Queue*) malloc(sizeof(struct Queue));
queue->maxSize = maxSize;
queue->front = queue->rear = -1;
queue->a = (int*) malloc(queue->maxSize * sizeof(int));
return queue;
}
// Checking for Overflow condition
int isFull(struct Queue* queue){
if ((queue->front == queue->rear + 1) ||
(queue->front == 0 && queue->rear == queue->maxSize - 1)){
return 1;
}
return 0;
}
// Checking for Underflow condition
int isEmpty(struct Queue* queue){
if (queue->front == -1)
{
return 1;
}
return 0;
}
// Function to do enqueue
void enqueue(struct Queue* queue,int value){
if (isFull(queue))
printf("Can't add the queue is full \n");
else
{
if (queue->front == -1)
queue->front = 0;
queue->rear = (queue->rear + 1) % queue->maxSize;
queue->a[queue->rear] = value;
printf("%d was added\n", value);
}
}
// Function to do dequeue
int dequeue(struct Queue* queue)
{
int item;
if (isEmpty(queue))
{
printf("Can't add the queue is empty \n");
return (-1);
}
else
{
item = queue->a[queue->front];
if (queue->front == queue->rear)
{
queue->front = queue->rear = -1 ;
}
else
{
queue->front = (queue->front + 1) % queue->maxSize;
}
printf("%d dequeued\n", item);
}
}
// Function to print the queue
void print(struct Queue* queue) {
int i;
if (isEmpty(queue))
printf("Empty Queue\n");
else {
printf("\nThe items in the queue are : \n");
for (i = queue->front; i != queue->rear; i = (i + 1) % queue->maxSize) {
printf("%d ", queue->a[i]);
}
printf("%d \n\n", queue->a[i]);
}
}
int main() {
struct Queue* queue = createQueue(6);
dequeue(queue);//Underflow condition
enqueue(queue,12);
enqueue(queue,14);
enqueue(queue,16);
enqueue(queue,18);
enqueue(queue,20);
print(queue);
dequeue(queue);
dequeue(queue);
print(queue);
enqueue(queue,22);
enqueue(queue,24);
enqueue(queue,26);
enqueue(queue,28);//Overflow condition
print(queue);
return 0;
}
Code in C++:
#include <bits/stdc++.h>
using namespace std;
// Basic class for queue
class Queue
{
private:
int front, rear, currSize;
unsigned maxCapacity;
int* a;
public:
Queue(int size){
maxCapacity = size;
front = -1;
currSize = 0;
rear = -1;
a = new int [maxCapacity];
}
void enqueue(int x);
int dequeue();
bool isEmpty();
bool isFull();
void display();
};
// Will return true if queue Current size has reached maxCapacity
bool Queue::isFull()
{
if ((front == rear + 1) ||
(front == 0 && rear == maxCapacity - 1)){
return true;
}
return false;
}
// Will return true if queue Current size is 0
bool Queue::isEmpty()
{
if (front == -1)
{
return true;
}
return false;
}
// Here we add new item to queue and change rear and Current size
void Queue::enqueue(int item)
{
if (isFull())
printf("Can't add the queue is full \n");
else
{
if (front == -1)
front = 0;
rear = (rear + 1) % maxCapacity;
a[rear] = item;
printf("%d was added\n", item);
}
}
// Here we remove or dequeue from queue and
//also change the front value and Current size of queue
int Queue::dequeue()
{
int item;
if (isEmpty())
{
printf("Can't add the queue is empty \n");
return (INT_MIN);
}
else
{
item = a[front];
if (front == rear)
{
front = rear = -1 ;
}
else
{
front = (front + 1) % maxCapacity;
}
printf("%d dequeued\n", item);
return item;
}
}
void Queue::display()
{
int i;
if (isEmpty())
printf("Empty Queue\n");
else {
printf("\nQueue: ");
for (i = front; i != rear; i = (i + 1) % maxCapacity) {
printf("%d ", a[i]);
}
printf("%d \n\n", a[i]);
}
}
// Main function to run queue program
int main()
{
Queue queue = Queue(6);
queue.dequeue();//Underflow condition
queue.enqueue(12);
queue.enqueue(14);
queue.enqueue(16);
queue.enqueue(18);
queue.enqueue(20);
queue.display();
queue.dequeue();
queue.dequeue();
queue.display();
queue.enqueue(22);
queue.enqueue(24);
queue.enqueue(26);
queue.enqueue(28);//Overflow condition
queue.display();
return 0;
}
Code in Java:
package DSA;
class CircularQueue {
int front, rear;
int capacity;
int curr_size;
int[] a;
CircularQueue(int cap)
{
capacity = cap;
front = -1;
rear = -1;
curr_size = 0;
a = new int[capacity];
}
boolean isFull()
{
return (front == rear + 1) ||
(front == 0 && rear == capacity - 1);
}
boolean isEmpty()
{
return front == -1;
}
// Method to add an item to the queue.
// It changes rear and size
void enqueue(int item)
{
if (isFull())
System.out.println("Can't add the queue is full ");
else
{
if (front == -1)
front = 0;
rear = (rear + 1) % capacity;
a[rear] = item;
System.out.println(item + " was added");
}
}
// Method to remove an item from queue.
// It changes front and size
int dequeue()
{
int item;
if (isEmpty())
{
System.out.println("Can't add the queue is empty");
return (Integer.MIN_VALUE);
}
else
{
item = a[front];
if (front == rear)
{
front = rear = -1 ;
}
else
{
front = (front + 1) % capacity;
}
System.out.println(item + " dequeued");
return item;
}
}
// Method to get front of queue
int front()
{
if (isEmpty())
return Integer.MIN_VALUE;
return a[front];
}
// Method to get rear of queue
int rear()
{
if (isEmpty())
return Integer.MIN_VALUE;
return a[rear];
}
void display()
{
int i;
if (isEmpty())
System.out.println("Empty Queue");
else {
System.out.println("\nQueue: ");
for (i = front; i != rear; i = (i + 1) % capacity) {
System.out.print(a[i]+ " ");
}
System.out.println(a[i]);
}
}
}
// Driver class
class Temp {
public static void main(String[] args)
{
CircularQueue queue = new CircularQueue(6);
queue.dequeue();//Underflow condition
queue.enqueue(12);
queue.enqueue(14);
queue.enqueue(16);
queue.enqueue(18);
queue.enqueue(20);
queue.display();
queue.dequeue();
queue.dequeue();
queue.display();
queue.enqueue(22);
queue.enqueue(24);
queue.enqueue(26);
queue.enqueue(28);//Overflow condition
queue.display();
}
}
Code in Python:
from sys import maxsize
class Queue:
def __init__(self, cap):
self.queue = [None] * cap
self.capacity = cap
self.front = -1
self.rear = -1
self.curr_size = 0
def is_full(self):
return (self.front == self.rear + 1) or (self.front == 0 and self.rear == self.capacity - 1)
def is_empty(self):
return self.front == -1
def enqueue(self, item):
if self.is_full():
print("Can't add the queue is full ")
else:
if self.front == -1:
self.front = 0
self.rear = (self.rear + 1) % self.capacity
self.queue[self.rear] = item
print(item, " was added")
def dequeue(self):
item = None
if self.is_empty():
print("Can't add the queue is empty");
return -maxsize
else:
item = self.queue[self.front]
if self.front == self.rear:
self.front = self.rear = -1
else:
self.front = (self.front + 1) % self.capacity
print(item, " dequeued")
return item
# function to display the queue
def display(self):
i = 0
if self.is_empty():
print("Empty Queue")
else:
print("\nQueue: ")
i = self.front
while i != self.rear:
print(self.queue[i], end=" ")
i = (i + 1) % self.capacity
print(self.queue[i])
# Driver Code
q = Queue(6)
q.dequeue() # Underflow condition
q.enqueue(12)
q.enqueue(14)
q.enqueue(16)
q.enqueue(18)
q.enqueue(20)
q.display()
q.dequeue()
q.dequeue()
q.display()
q.enqueue(22)
q.enqueue(24)
q.enqueue(26)
q.enqueue(28) # Overflow condition
q.display()
Try It Yourself, Practicing the Code
Now that you've seen the code for implementing a queue, it's time to roll up your sleeves and try it out for yourself.๐ช
Putting Queues into Action ๐ ๏ธ
Queues can be implemented using various data structures, but one common method is using an array. Take a look at this basic C/C++ code:
Queue implementation using c/c++ (Method 1).Here i had chosen c language
Stay Curious and Experiment! ๐
As we conclude our journey into the realm of queues, I encourage you to stay curious and experiment. Create your own queue implementations, explore different types of queues, and test their performance in various scenarios.
In our next session, we'll embark on another adventure, delving into more captivating data structures and algorithms that will expand your programming horizons. Get ready for more magic in the world of computer science and coding!
Remember, every line of code you write is a step forward in your journey to becoming a coding wizard. ๐ช๐ปโจ