0
0
CHow-ToBeginner · 4 min read

How to Implement Circular Queue in C: Simple Guide with Example

A circular queue in C is implemented using an array with two pointers: front and rear. These pointers wrap around the array when they reach the end, allowing efficient use of space without shifting elements.
📐

Syntax

A circular queue uses an array and two integer variables: front and rear. The front points to the first element, and rear points to the last element. When inserting or deleting, these pointers move forward and wrap to the start when reaching the array's end.

Key operations include:

  • Enqueue: Add an element at rear and move rear forward.
  • Dequeue: Remove an element from front and move front forward.
  • Check full: When next position of rear equals front.
  • Check empty: When front equals -1 or front == -1 depending on implementation.
c
int queue[MAX_SIZE];
int front = -1;
int rear = -1;

// To check if queue is full
int isFull() {
    return ((rear + 1) % MAX_SIZE == front);
}

// To check if queue is empty
int isEmpty() {
    return (front == -1);
}

// To add element
void enqueue(int value) {
    if (isFull()) {
        // Queue is full
    } else {
        if (front == -1) front = 0;
        rear = (rear + 1) % MAX_SIZE;
        queue[rear] = value;
    }
}

// To remove element
int dequeue() {
    int value = -1;
    if (isEmpty()) {
        // Queue is empty
    } else {
        value = queue[front];
        if (front == rear) {
            front = rear = -1; // Queue is now empty
        } else {
            front = (front + 1) % MAX_SIZE;
        }
    }
    return value;
}
💻

Example

This example shows a complete circular queue implementation with enqueue, dequeue, and display functions. It demonstrates adding and removing elements while wrapping around the array.

c
#include <stdio.h>
#define MAX_SIZE 5

int queue[MAX_SIZE];
int front = -1;
int rear = -1;

int isFull() {
    return ((rear + 1) % MAX_SIZE == front);
}

int isEmpty() {
    return (front == -1);
}

void enqueue(int value) {
    if (isFull()) {
        printf("Queue is full\n");
        return;
    }
    if (front == -1) front = 0;
    rear = (rear + 1) % MAX_SIZE;
    queue[rear] = value;
    printf("Enqueued: %d\n", value);
}

int dequeue() {
    if (isEmpty()) {
        printf("Queue is empty\n");
        return -1;
    }
    int value = queue[front];
    if (front == rear) {
        front = rear = -1;
    } else {
        front = (front + 1) % MAX_SIZE;
    }
    printf("Dequeued: %d\n", value);
    return value;
}

void display() {
    if (isEmpty()) {
        printf("Queue is empty\n");
        return;
    }
    printf("Queue elements: ");
    int i = front;
    while (1) {
        printf("%d ", queue[i]);
        if (i == rear) break;
        i = (i + 1) % MAX_SIZE;
    }
    printf("\n");
}

int main() {
    enqueue(10);
    enqueue(20);
    enqueue(30);
    enqueue(40);
    display();
    dequeue();
    dequeue();
    display();
    enqueue(50);
    enqueue(60);
    enqueue(70); // This should show full
    display();
    return 0;
}
Output
Enqueued: 10 Enqueued: 20 Enqueued: 30 Enqueued: 40 Queue elements: 10 20 30 40 Dequeued: 10 Dequeued: 20 Queue elements: 30 40 Enqueued: 50 Enqueued: 60 Queue is full Queue elements: 30 40 50 60
⚠️

Common Pitfalls

Common mistakes when implementing circular queues include:

  • Not wrapping front and rear using modulo, causing out-of-bound errors.
  • Incorrectly checking full condition; it must be (rear + 1) % MAX_SIZE == front.
  • Confusing empty and full states when front == rear. Using front == -1 to indicate empty helps.
  • Forgetting to reset front and rear to -1 when queue becomes empty after dequeue.

Example of wrong full check:

c
int isFullWrong() {
    return (rear == MAX_SIZE - 1); // Wrong for circular queue
}

// Correct way:
int isFullCorrect() {
    return ((rear + 1) % MAX_SIZE == front);
}
📊

Quick Reference

  • Enqueue: Move rear = (rear + 1) % MAX_SIZE, insert element.
  • Dequeue: Remove element at front, then front = (front + 1) % MAX_SIZE.
  • Empty: front == -1.
  • Full: (rear + 1) % MAX_SIZE == front.
  • Reset: When queue empties, set front = rear = -1.

Key Takeaways

Use modulo (%) to wrap front and rear pointers in the array.
Check full condition with (rear + 1) % MAX_SIZE == front to avoid overflow.
Initialize front and rear to -1 to represent an empty queue.
Reset front and rear to -1 when queue becomes empty after dequeue.
Display elements by iterating from front to rear with wrapping.