Tutorial

How to Create a Queue in C (With Code Examples

Updated on May 2, 2025
authorauthor

By Safa Mulani and Anish Singh Walia

How to Create a Queue in C (With Code Examples

Introduction

A queue in C is basically a linear data structure to store and manipulate the data elements. It follows the order of First In First Out (FIFO).

In queues, the first element entered into the array is the first element to be removed from the array.

For example, let’s consider the scenario of a bus-ticket booking stall. Here, the fashion of a C programming queue is followed. The tickets are distributed on the first-come-first-serve basis i.e. the first one to enter is the first one to be served with the tickets.

A queue is open at both ends. One end is provided for the insertion of data and the other end for the deletion of data.

A queue can be implemented with any programming language such as C, Java, Python, etc.

Operations Associated with a Queue in C

A queue being an Abstract Data Structure provides the following operations for manipulation on the data elements:

  • isEmpty(): To check if the queue is empty
  • isFull(): To check whether the queue is full or not
  • dequeue(): Removes the element from the frontal side of the queue
  • enqueue(): It inserts elements to the end of the queue
  • Front: Pointer element responsible for fetching the first element from the queue
  • Rear: Pointer element responsible for fetching the last element from the queue

Working of Queue Data Structure

Queue follows the First-In-First-Out pattern. The first element is the first to be pulled out from the list of elements.

  • Front and Rear pointers keep the record of the first and last element in the queue.
  • At first, we need to initialize the queue by setting Front = -1 and Rear = -1
  • In order to insert the element (enqueue), we need to check whether the queue is already full i.e. check the condition for Overflow. If the queue is not full, we’ll have to increment the value of the Rear index by 1 and place the element at the position of the Rear pointer variable. When we get to insert the first element in the queue, we need to set the value of Front to 0.
  • In order to remove the element (dequeue) from the queue, we need to check whether the queue is already empty i.e. check the condition for Underflow. If the queue is not empty, we’ll have to remove and return the element at the position of the Front pointer, and then increment the Front index value by 1. When we get to remove the last element from the queue, we will have to set the values of the Front and Rear index to -1.

Implementation of Queue in C

Queues in C can be implemented using Arrays, Lists, Structures, etc. Below here we have implemented queues using Arrays in C.

Example:

#include <stdio.h>
# define SIZE 100
void enqueue();
void dequeue();
void show();
int inp_arr[SIZE];
int Rear = - 1;
int Front = - 1;
main()
{
    int ch;
    while (1)
    {
        printf("1.Enqueue Operation\n");
        printf("2.Dequeue Operation\n");
        printf("3.Display the Queue\n");
        printf("4.Exit\n");
        printf("Enter your choice of operations : ");
        scanf("%d", &ch);
        switch (ch)
        {
            case 1:
            enqueue();
            break;
            case 2:
            dequeue();
            break;
            case 3:
            show();
            break;
            case 4:
            exit(0);
            default:
            printf("Incorrect choice \n");
        } 
    } 
} 
 
void enqueue()
{
    int insert_item;
    if (Rear == SIZE - 1)
       printf("Overflow \n");
    else
    {
        if (Front == - 1)
      
        Front = 0;
        printf("Element to be inserted in the Queue\n : ");
        scanf("%d", &insert_item);
        Rear = Rear + 1;
        inp_arr[Rear] = insert_item;
    }
} 
 
void dequeue()
{
    if (Front == - 1 || Front > Rear)
    {
        printf("Underflow \n");
        return ;
    }
    else
    {
        printf("Element deleted from the Queue: %d\n", inp_arr[Front]);
        Front = Front + 1;
    }
} 
 
void show()
{
    
    if (Front == - 1)
        printf("Empty Queue \n");
    else
    {
        printf("Queue: \n");
        for (int i = Front; i <= Rear; i++)
            printf("%d ", inp_arr[i]);
        printf("\n");
    }
} 

Output:

1.Enqueue Operation
2.Dequeue Operation
3.Display the Queue
4.Exit
Enter your choice of operations : 1
Element to be inserted in the Queue: 10

1.Enqueue Operation
2.Dequeue Operation
3.Display the Queue
4.Exit
Enter your choice of operations : 1
Element to be inserted in the Queue: 20

1.Enqueue Operation
2.Dequeue Operation
3.Display the Queue
4.Exit
Enter your choice of operations : 3
Queue: 
10 20 

1.Enqueue Operation
2.Dequeue Operation
3.Display the Queue
4.Exit
Enter your choice of operations : 2
Element deleted from the Queue: 10

1.Enqueue Operation
2.Dequeue Operation
3.Display the Queue
4.Exit
Enter your choice of operations: 3
Queue: 
20 

Implementation of Queue using Stacks

Stack Data Structure can be used to implement the operations of the queue. We’ll need two stacks to implement a queue using them. Before you work through the examples below, make sure you understand the functioning of stacks very well.

A queue can be implemented using Stacks by either of the following ways:

  • Making the enqueue operation costly
  • Making the dequeue operation costly

Method 1: Making the enqueue Operation Costly

Let us assume two stacks: S1 and S2 to implement queue operations using the same.

  • If S1 is not empty, push all elements to stack 2 (S2)
  • In order to perform the enqueue operation, we will assume ‘x’ to be the element to be entered into the queue. We will push ‘x’ back to Stack S1 so it comes up on the top.
  • Further, push all the elements of stack S2 back to Stack S1

Note: The time complexity of the enqueue operation would be O(n).

  • In order to perform dequeue operation, we’ll need to pop an item from the Stack S1 since now the first inserted element is on the top in S1 instead of being at the bottom.

Note: The time complexity of the dequeue operation would be O(1).

If you analyze the time complexities of the Enqueue and Dequeue operations using Stack, you’ll find out that the Enqueue operation is much costlier than the Dequeue operation.

Thus, as mentioned above, we make the first entered or the oldest entered element to remain at the top of Stack S1 so that it gets removed when the Dequeue operation is invoked.

Method 2: Making the Dequeue operation costly

Let us again assume two Stacks: S1 and S2 to implement queue operations using the same.

  • In order to implement enqueue operation, we insert the newly entered element at the top of Stack S1. Thus, the time complexity of the Enqueue operation using Stacks becomes O(1).
  • For the implementation of dequeue operation, it checks for the Underflow condition of Stack S1 and S2. If both the Stacks stands out to be empty, an error would be raised.
  • If the Stack S2 is empty and S1 is not empty, then all the elements from Stack S1 are moved to Stack S2 and the top element of Stack S2 is popped out and returned out of the Dequeue operation.
  • Thus, the time complexity of the dequeue operation using Stacks becomes O(n).

Applications of Queue Data Structure

  • CPU Scheduling
  • Disk Scheduling
  • Asynchronous data transfer between processors such as File IO, etc.
  • Breadth-First Search Algorithm (BFS)

Use in Simulations, Scheduling, and Task Management

Queues have numerous applications in various fields, including simulations, scheduling, and task management. Here are some examples:

Simulations

In simulations, queues can be used to model real-world scenarios where entities are processed in a First-In-First-Out (FIFO) order. For instance, in a simulation of a bank, customers can be represented as elements in a queue, and the bank tellers can be thought of as the processing units that serve the customers in the order they arrive.

Example in C:

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

// Structure to represent a queue node
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// Function to enqueue a new customer
void enqueue(Node** front, Node** rear, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (*rear == NULL) {
        *front = *rear = newNode;
    } else {
        (*rear)->next = newNode;
        *rear = newNode;
    }
}

// Function to dequeue a customer
int dequeue(Node** front, Node** rear) {
    if (*front == NULL) {
        printf("Queue is empty\n");
        return -1;
    }
    Node* temp = *front;
    int data = temp->data;
    *front = (*front)->next;
    if (*front == NULL) {
        *rear = NULL;
    }
    free(temp);
    return data;
}

int main() {
    Node* front = NULL, *rear = NULL;
    // Enqueue customers
    enqueue(&front, &rear, 1);
    enqueue(&front, &rear, 2);
    enqueue(&front, &rear, 3);
    // Dequeue customers
    printf("Dequeued customer: %d\n", dequeue(&front, &rear));
    printf("Dequeued customer: %d\n", dequeue(&front, &rear));
    printf("Dequeued customer: %d\n", dequeue(&front, &rear));
    return 0;
}

Scheduling

In scheduling, queues can be used to manage tasks or processes that need to be executed in a specific order. For example, in an operating system, processes can be placed in a queue and executed by the CPU in the order they were received. This ensures that each process gets a fair share of the CPU time and prevents any single process from monopolizing the CPU.

Example Implementation in C:

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

// Structure to represent a process
typedef struct Process {
    int pid;
    int priority;
    struct Process* next;
} Process;

// Function to add a process to the queue
void addProcess(Process** front, Process** rear, int pid, int priority) {
    Process* newNode = (Process*)malloc(sizeof(Process));
    newNode->pid = pid;
    newNode->priority = priority;
    newNode->next = NULL;
    if (*rear == NULL) {
        *front = *rear = newNode;
    } else {
        (*rear)->next = newNode;
        *rear = newNode;
    }
}

// Function to execute processes in order of priority
void executeProcesses(Process** front) {
    Process* temp = *front;
    while (temp != NULL) {
        printf("Executing process with PID: %d and Priority: %d\n", temp->pid, temp->priority);
        temp = temp->next;
    }
}

int main() {
    Process* front = NULL, *rear = NULL;
    // Add processes to the queue
    addProcess(&front, &rear, 1, 3);
    addProcess(&front, &rear, 2, 2);
    addProcess(&front, &rear, 3, 1);
    // Execute processes in order of priority
    executeProcesses(&front);
    return 0;
}

Task Management

In task management, queues can be used to prioritize and manage tasks efficiently. For instance, in a project management scenario, tasks can be represented as elements in a queue, and the project manager can prioritize tasks based on their urgency and importance. This ensures that critical tasks are addressed first, and the project progresses in an orderly manner.

Example Implementation in C:

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

// Structure to represent a task
typedef struct Task {
    char name[100];
    int priority;
    struct Task* next;
} Task;

// Function to add a task to the queue
void addTask(Task** front, Task** rear, char* name, int priority) {
    Task* newNode = (Task*)malloc(sizeof(Task));
    strcpy(newNode->name, name);
    newNode->priority = priority;
    newNode->next = NULL;
    if (*rear == NULL) {
        *front = *rear = newNode;
    } else {
        (*rear)->next = newNode;
        *rear = newNode;
    }
}

// Function to manage tasks in order of priority
void manageTasks(Task** front) {
    Task* temp = *front;
    while (temp != NULL) {
        printf("Managing task: %s with Priority: %d\n", temp->name, temp->priority);
        temp = temp->next;
    }
}

int main() {
    Task* front = NULL, *rear = NULL;
    // Add tasks to the queue
    addTask(&front, &rear, "Task A", 2);
    addTask(&front, &rear, "Task B", 1);
    addTask(&front, &rear, "Task C", 3);
    // Manage tasks in order of priority
    manageTasks(&front);
    return 0;
}

These are just a few examples of how queues can be applied in simulations, scheduling, and task management. The use of queues in these contexts helps to ensure that processes are executed efficiently, fairly, and in the correct order.

Common Errors and Debugging

Array overflow/underflow in fixed queues

When implementing a fixed-size queue using an array, it’s essential to check for overflow and underflow conditions to prevent errors. Overflow occurs when trying to enqueue an element into a full queue, while underflow occurs when trying to dequeue from an empty queue. For example, if you have a queue of size 5 and you try to enqueue a sixth element, it will result in an overflow error.

Example Code:

void enqueue(int* queue, int* front, int* rear, int size, int element) {
    if (*rear == size - 1) {
        printf("Overflow error: Queue is full.\n");
        return;
    }
    queue[++(*rear)] = element;
    if (*front == -1) *front = 0;
}

int dequeue(int* queue, int* front, int* rear) {
    if (*front == -1) {
        printf("Underflow error: Queue is empty.\n");
        return -1;
    }
    int element = queue[*front];
    if (*front == *rear) {
        *front = *rear = -1;
    } else {
        (*front)++;
    }
    return element;
}
### Forgetting to free memory in linked list queues

In linked list implementations of queues, it's crucial to free the memory of dequeued elements to prevent memory leaks. Failing to do so can lead to memory exhaustion over time. For instance, if you dequeue an element but don't free its memory, the memory will remain allocated, causing a memory leak.

**Example Code:**
```c
void dequeue(Node** front, Node** rear) {
    if (*front == NULL) {
        printf("Queue is empty\n");
        return;
    }
    Node* temp = *front;
    *front = (*front)->next;
    if (*front == NULL) *rear = NULL; // Update rear if the queue becomes empty
    free(temp); // Free the memory of the dequeued element
}
### Incorrect front/rear pointer manipulation

Incorrect manipulation of the front and rear pointers can lead to errors in queue operations. For example, if you incorrectly update the rear pointer during enqueue, it can result in elements being lost or the queue becoming corrupted.

**Example Code:**
```c
void enqueue(Node** front, Node** rear, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (*rear == NULL) {
        *front = *rear = newNode;
    } else {
        (*rear)->next = newNode; // Correctly update the rear pointer
        *rear = newNode;
    }
}

Infinite loops in dequeue() without NULL checks

When implementing the dequeue operation, it’s essential to check if the queue is empty before attempting to dequeue an element. Without this check, the dequeue operation can result in an infinite loop if the queue is empty, leading to a program crash or unexpected behavior.

Example Code:

int dequeue(Node** front, Node** rear) {
    if (*front == NULL) {
        printf("Queue is empty\n");
        return -1; // Exit if the queue is empty
    }
    int data = (*front)->data;
    Node* temp = *front;
    *front = (*front)->next;
    if (*front == NULL) *rear = NULL; // Update rear if the queue becomes empty
    free(temp); // Free the memory of the dequeued element
    return data;
}

Comparison between static and dynamic memory queues

Static memory queues are fixed in size and cannot be resized once allocated. This can lead to memory wastage if the queue is not used to its full capacity.

Dynamic memory queues, on the other hand, can be resized dynamically as needed, making them more flexible and efficient.

Queue Type Memory Allocation Space Complexity Flexibility
Static Fixed at compile time O(n) Low
Dynamic Allocated at runtime O(1) High

Note: In the table above, ‘n’ represents the fixed size of the static queue, and ‘1’ represents the dynamic allocation of memory as needed.

FAQs

How do you implement a queue in C?

To implement a queue in C, you can use either arrays or linked lists. Here’s an example implementation using linked lists:

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

typedef struct Node {
    int data;
    struct Node* next;
} Node;

typedef struct Queue {
    Node* front;
    Node* rear;
} Queue;

void enqueue(Queue* q, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (q->rear == NULL) {
        q->front = q->rear = newNode;
    } else {
        q->rear->next = newNode;
        q->rear = newNode;
    }
}

int dequeue(Queue* q) {
    if (q->front == NULL) {
        printf("Queue is empty\n");
        return -1;
    }
    Node* temp = q->front;
    int data = temp->data;
    q->front = q->front->next;
    if (q->front == NULL) q->rear = NULL;
    free(temp);
    return data;
}
// Example usage
int main() {
    Queue q;
    q.front = q.rear = NULL;
    enqueue(&q, 1);
    enqueue(&q, 2);
    printf("Dequeued element: %d\n", dequeue(&q));
    printf("Dequeued element: %d\n", dequeue(&q));
    return 0;
}

Does C have a built-in queue?

No, C does not have a built-in queue data structure. However, you can implement a queue using arrays or linked lists as shown above.

Is there a queue library in C?

No, there is no standard library in C that provides a queue data structure. You need to implement it yourself or use a third-party library.

How to create a queue?

To create a queue, you need to define a structure to represent the queue and its nodes. Then, implement functions for enqueue and dequeue operations. Here’s an example implementation in C:

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

typedef struct Node {
    int data;
    struct Node* next;
} Node;

typedef struct Queue {
    Node* front;
    Node* rear;
} Queue;

void enqueue(Queue* q, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (q->rear == NULL) {
        q->front = q->rear = newNode;
    } else {
        q->rear->next = newNode;
        q->rear = newNode;
    }
}

int dequeue(Queue* q) {
    if (q->front == NULL) {
        printf("Queue is empty\n");
        return -1;
    }
    Node* temp = q->front;
    int data = temp->data;
    q->front = q->front->next;
    if (q->front == NULL) q->rear = NULL;
    free(temp);
    return data;
}

int main() {
    Queue q;
    q.front = q.rear = NULL;
    enqueue(&q, 1);
    enqueue(&q, 2);
    printf("Dequeued element: %d\n", dequeue(&q));
    printf("Dequeued element: %d\n", dequeue(&q));
    return 0;
}

What is the easiest way to implement a queue?

The easiest way to implement a queue is using linked lists. This approach allows for dynamic memory allocation and easy insertion and deletion of elements. Here’s an example of how to build a queue in C using linked lists:

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

typedef struct Node {
    int data;
    struct Node* next;
} Node;

typedef struct Queue {
    Node* front;
    Node* rear;
} Queue;

void enqueue(Queue* q, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (q->rear == NULL) {
        q->front = q->rear = newNode;
    } else {
        q->rear->next = newNode;
        q->rear = newNode;
    }
}

int dequeue(Queue* q) {
    if (q->front == NULL) {
        printf("Queue is empty\n");
        return -1;
    }
    Node* temp = q->front;
    int data = temp->data;
    q->front = q->front->next;
    if (q->front == NULL) q->rear = NULL;
    free(temp);
    return data;
}

int main() {
    Queue q;
    q.front = q.rear = NULL;
    enqueue(&q, 1);
    enqueue(&q, 2);
    printf("Dequeued element: %d\n", dequeue(&q));
    printf("Dequeued element: %d\n", dequeue(&q));
    return 0;
}

How to create a stack in C?

Creating a stack in C is similar to creating a queue. You can use arrays or linked lists to implement a stack. Here’s an example implementation using linked lists:

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

typedef struct Node {
    int data;
    struct Node* next;
} Node;

typedef struct Stack {
    Node* top;
} Stack;

void push(Stack* s, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = s->top;
    s->top = newNode;
}

int pop(Stack* s) {
    if (s->top == NULL) {
        printf("Stack is empty\n");
        return -1;
    }
    Node* temp = s->top;
    int data = temp->data;
    s->top = s->top->next;
    free(temp);
    return data;
}
// Example usage
int main() {
    Stack s;
    s.top = NULL;
    push(&s, 1);
    push(&s, 2);
    printf("Popped element: %d\n", pop(&s));
    printf("Popped element: %d\n", pop(&s));
    return 0;
}

What is a queue in C and why is it used?

A queue in C is a linear data structure that follows the First-In-First-Out (FIFO) principle. It is used to implement scenarios where elements need to be processed in the order they were received, such as job scheduling, print queues, and network protocols.

How do you implement a queue using arrays in C?

Implementing a queue using arrays in C involves defining a structure to represent the queue and its elements. Here’s an example implementation:

#include <stdio.h>

#define SIZE 100

typedef struct Queue {
    int elements[SIZE];
    int front;
    int rear;
} Queue;

void enqueue(Queue* q, int data) {
    if (q->rear == SIZE - 1) {
        printf("Queue is full\n");
        return;
    }
    q->elements[++q->rear] = data;
    if (q->front == -1) q->front = 0;
}

int dequeue(Queue* q) {
    if (q->front == -1 || q->front > q->rear) {
        printf("Queue is empty\n");
        return -1;
    }
    return q->elements[q->front++];
}
// Example usage
int main() {
    Queue q;
    q.front = q.rear = -1;
    enqueue(&q, 1);
    enqueue(&q, 2);
    printf("Dequeued element: %d\n", dequeue(&q));
    printf("Dequeued element: %d\n", dequeue(&q));
    return 0;
}

How is a queue implemented using linked lists?

A queue implemented using linked lists involves defining a structure to represent the queue and its nodes. Each node contains data and a pointer to the next node. The queue structure contains pointers to the front and rear nodes. Enqueue operation involves adding a new node at the rear, and dequeue operation involves removing a node from the front.

Here’s a simple example of how a queue can be implemented using linked lists in C:

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

// Structure to represent a queue node
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// Structure to represent the queue
typedef struct Queue {
    Node* front;
    Node* rear;
} Queue;

// Function to enqueue a new element
void enqueue(Queue* q, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (q->rear == NULL) {
        q->front = q->rear = newNode;
    } else {
        q->rear->next = newNode;
        q->rear = newNode;
    }
}

// Function to dequeue an element
int dequeue(Queue* q) {
    if (q->front == NULL) {
        printf("Queue is empty\n");
        return -1;
    }
    Node* temp = q->front;
    int data = temp->data;
    q->front = q->front->next;
    if (q->front == NULL) {
        q->rear = NULL;
    }
    free(temp);
    return data;
}

int main() {
    Queue q;
    q.front = q.rear = NULL;
    enqueue(&q, 1);
    enqueue(&q, 2);
    printf("Dequeued element: %d\n", dequeue(&q));
    printf("Dequeued element: %d\n", dequeue(&q));
    return 0;
}

What is the difference between a queue and a stack?

The main difference between a queue and a stack is the order in which elements are added and removed. A queue follows the First-In-First-Out (FIFO) principle, whereas a stack follows the Last-In-First-Out (LIFO) principle.

Here’s a simple example in C to illustrate the difference:

#include <stdio.h>

// Example of a stack
void stackExample() {
    int stack[3] = {1, 2, 3}; // Elements are added in this order
    printf("Stack elements: ");
    for (int i = 2; i >= 0; i--) { // Elements are removed in reverse order
        printf("%d ", stack[i]);
    }
    printf("\n");
}

// Example of a queue
void queueExample() {
    int queue[3] = {1, 2, 3}; // Elements are added in this order
    printf("Queue elements: ");
    for (int i = 0; i < 3; i++) { // Elements are removed in the same order
        printf("%d ", queue[i]);
    }
    printf("\n");
}

int main() {
    printf("Stack Example:\n");
    stackExample();
    printf("Queue Example:\n");
    queueExample();
    return 0;
}

What are the common queue operations in C?

The common queue operations in C are:

  • Enqueue: Adds an element to the rear of the queue.
  • Dequeue: Removes an element from the front of the queue.
  • IsEmpty: Checks if the queue is empty.
  • IsFull: Checks if the queue is full.
  • Front: Returns the element at the front of the queue without removing it.
  • Rear: Returns the element at the rear of the queue without removing it.

How do you check if a queue is full or empty?

To check if a queue is full or empty, you can use the following conditions:

  • For an array-based queue: if (q->rear == SIZE - 1) for full, if (q->front == -1 || q->front > q->rear) for empty.
  • For a linked list-based queue: if (q->rear == NULL) for empty.

Array-Based Queue Example in C:

#include <stdio.h>

#define SIZE 5

typedef struct {
    int data[SIZE];
    int front, rear;
} Queue;

void initQueue(Queue* q) {
    q->front = q->rear = -1;
}

int isEmpty(Queue* q) {
    return q->front == -1 || q->front > q->rear;
}

int isFull(Queue* q) {
    return q->rear == SIZE - 1;
}

int main() {
    Queue q;
    initQueue(&q);

    printf("Is queue empty? %d\n", isEmpty(&q)); // Expected output: 1 (true)
    printf("Is queue full? %d\n", isFull(&q)); // Expected output: 0 (false)

    // Example of adding elements to the queue
    q.rear = 0;
    q.data[0] = 1; // Assuming enqueue operation is implemented

    printf("Is queue empty? %d\n", isEmpty(&q)); // Expected output: 0 (false)
    printf("Is queue full? %d\n", isFull(&q)); // Expected output: 0 (false)

    // Example of adding more elements to the queue until it's full
    for (int i = 1; i < SIZE; i++) {
        q.data[i] = i + 1; // Assuming enqueue operation is implemented
        q.reear++;
    }

    printf("Is queue empty? %d\n", isEmpty(&q)); // Expected output: 0 (false)
    printf("Is queue full? %d\n", isFull(&q)); // Expected output: 1 (true)

    return 0;
}

Linked List-Based Queue Example in C:

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

typedef struct Node {
    int data;
    struct Node* next;
} Node;

typedef struct {
    Node* front, *rear;
} Queue;

void initQueue(Queue* q) {
    q->front = q->rear = NULL;
}

int isEmpty(Queue* q) {
    return q->rear == NULL;
}

int main() {
    Queue q;
    initQueue(&q);

    printf("Is queue empty? %d\n", isEmpty(&q)); // Expected output: 1 (true)

    // Example of adding elements to the queue
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = 1; // Assuming enqueue operation is implemented
    q.rear = newNode;
    q.front = newNode;

    printf("Is queue empty? %d\n", isEmpty(&q)); // Expected output: 0 (false)

    return 0;
}

What is a circular queue and how is it different?

A circular queue is a variant of the queue data structure where the last element points back to the first element, forming a circle. This allows for efficient use of memory and enables the queue to wrap around when it reaches its capacity. The main difference is that the rear element points back to the front element, allowing for circular traversal.

Here’s a simple example in C to illustrate the difference:

#include <stdio.h>

// Structure to represent a node in the circular queue
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// Function to insert an element into the circular queue
void enqueue(Node** front, Node** rear, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    if (*rear == NULL) {
        *front = *rear = newNode;
        newNode->next = newNode; // Circular link
    } else {
        newNode->next = (*front);
        (*rear)->next = newNode;
        *rear = newNode;
    }
}

// Function to display the elements of the circular queue
void display(Node* front) {
    Node* temp = front;
    do {
        printf("%d ", temp->data);
        temp = temp->next;
    } while (temp != front);
    printf("\n");
}

int main() {
    Node* front = NULL, *rear = NULL;
    // Enqueue elements
    enqueue(&front, &rear, 1);
    enqueue(&front, &rear, 2);
    enqueue(&front, &rear, 3);
    // Display the circular queue
    printf("Circular Queue: ");
    display(front);
    return 0;
}

Conclusion

In this article, we have understood the working of queue data structure and have also shadowed over the implementation of queues using stack data structure. We have also discussed the applications of queues in simulations, scheduling, and task management.

References

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
February 4, 2022

Hi, this code doesn’t run because you never defined exit()

- neil

    Join the Tech Talk
    Success! Thank you! Please check your email for further details.

    Please complete your information!

    Become a contributor for community

    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

    DigitalOcean Documentation

    Full documentation for every DigitalOcean product.

    Resources for startups and SMBs

    The Wave has everything you need to know about building a business, from raising funding to marketing your product.

    Get our newsletter

    Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

    New accounts only. By submitting your email you agree to our Privacy Policy

    The developer cloud

    Scale up as you grow — whether you're running one virtual machine or ten thousand.

    Get started for free

    Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

    *This promotional offer applies to new accounts only.