CSE NotesCSE Notes
Simplifying Complexity

Circular Queue Structure

A circular queue is implemented using a fixed-size array along with two pointers, front and rear. Below is the structure definition for a circular queue:

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 5 // Define maximum size of the queue

typedef struct {
int items[MAX_SIZE];
int front;
int rear;
} CircularQueue;

Initialize the Queue

This function initializes the circular queue by setting front and rear to -1.

void initializeQueue(CircularQueue* q) {
q->front = -1;
q->rear = -1;
}

1. Enqueue Operation

This function adds an element to the queue.

int enqueue(CircularQueue* q, int value) {
if ((q->rear + 1) % MAX_SIZE == q->front) {
printf(“Queue is full\n”);
return -1; // Queue is full
}
if (q->front == -1) { // First element
q->front = 0;
}
q->rear = (q->rear + 1) % MAX_SIZE;
q->items[q->rear] = value;
return 0; // Success
}

Analysis:

  • Time Complexity: O(1) – Constant time operation.
  • Space Complexity: O(1) – No additional space is required.

2. Dequeue Operation

This function removes an element from the queue.

int dequeue(CircularQueue* q) {
if (q->front == -1) {
printf(“Queue is empty\n”);
return -1; // Queue is empty
}
int item = q->items[q->front];
if (q->front == q->rear) { // Queue is now empty
q->front = -1;
q->rear = -1;
} else {
q->front = (q->front + 1) % MAX_SIZE;
}
return item; // Return dequeued item
}

Analysis:

  • Time Complexity: O(1) – Constant time operation.
  • Space Complexity: O(1) – No additional space is required.

3. Peek/Front Operation

This function returns the front element of the queue without removing it.

int peek(CircularQueue* q) {
if (q->front == -1) {
printf(“Queue is empty\n”);
return -1; // Queue is empty
}
return q->items[q->front]; // Return front item
}

Analysis:

  • Time Complexity: O(1) – Constant time operation.
  • Space Complexity: O(1) – No additional space is required.

4. IsEmpty Operation

This function checks if the queue is empty.

int isEmpty(CircularQueue* q) {
return q->front == -1; // Returns 1 if empty, otherwise 0
}

int isEmpty(CircularQueue* q) {
return q->front == -1; // Returns 1 if empty, otherwise 0
}

Analysis:

  • Time Complexity: O(1) – Constant time check.
  • Space Complexity: O(1).

5. IsFull Operation

This function checks if the queue is full.

int isFull(CircularQueue* q) {
return (q->rear + 1) % MAX_SIZE == q->front; // Returns 1 if full, otherwise 0
}

Analysis:

  • Time Complexity: O(1) – Constant time check.
  • Space Complexity: O(1).

6. Display Operation

This function displays all the elements in the queue.

void display(CircularQueue* q) {
if (isEmpty(q)) {
printf(“Queue is empty\n”);
return;
}
int i = q->front;
while (1) {
printf(“%d “, q->items[i]);
if (i == q->rear)
break;
i = (i + 1) % MAX_SIZE;
}
printf(“\n”);
}

Analysis:

  • Time Complexity: O(n) – Linear time to display all elements.
  • Space Complexity: O(1) – No additional space is required.

Example Usage

Here’s how to use the circular queue in a simple program:

int main() {
CircularQueue q;
initializeQueue(&q);

enqueue(&q, 10);
enqueue(&q, 20);
enqueue(&q, 30);
display(&q); // Output: 10 20 30

printf(“Dequeued: %d\n”, dequeue(&q)); // Output: 10
display(&q); // Output: 20 30

enqueue(&q, 40);
enqueue(&q, 50);
enqueue(&q, 60); // Queue is full
display(&q); // Output: 20 30 40 50

return 0;
}

The circular queue implementation in C provides efficient operations for enqueuing, dequeuing, and checking the state of the queue. All primary operations (enqueue, dequeue, peek, isEmpty, and isFull) run in constant time O(1), making it a powerful tool for scenarios requiring a fixed-size queue.