Implement Queue in C – Example

In the previous post, we implemented stacks, which is quite useful in real life. However, there is another data structure that we see everyday around us, which we call it a queue. In computer science, we can find its applications in simulations, print spooling, processes, and many more. Before starting to implement queue with an example in C, I recommend you to understand about self-referential structures. The post here will be useful to understand about self-referential structures and linked list.

Implement queue in C - Example. An example to implement a queue in C programming language.
A queue

Meanwhile, let’s see the code below:

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

// Self-referential Structure
struct queueNode {
    char data;  // A character data in the queue
    struct queueNode *nextPtr;   // Pointer to next node
}; // end struct queuNode

typedef struct queueNode QueueNode; // alias for the struct
typedef QueueNode *QueueNodePtr;  // alias for QueueNode*

// Declarations
void enqueue(QueueNodePtr *headPtr, QueueNodePtr *tailPtr, char value);
char dequeue(QueueNodePtr *headPtr, QueueNodePtr *tailPtr);
int isEmpty(QueueNodePtr headPtr);
void showQueue(QueueNodePtr currentPtr); 
void showMenu(void);

int main() {
    // Initially, there are no nodes
    QueueNodePtr headPtr = NULL;
    QueueNodePtr tailPtr = NULL;
    // User's choice
    unsigned int ch;
    // User's entered character
    char item;
    
    // Display the menu
    showMenu();
    printf("? ");
    scanf("%u", &ch);
    
    // Loop unless user chooses 3
    while(ch != 3) {
        switch(ch) {
            case 1:
                printf("Enter a character: ");
                scanf("\n%c", &item);
                
                // insert the item in queue
                enqueue(&headPtr, &tailPtr, item);
                showQueue(headPtr);
                break;
            case 2:
                // if queue is not empty
                if(!isEmpty(headPtr)) {
                    item = dequeue(&headPtr, &tailPtr);
                    printf("%c is dequeued.\n", item);
                }// end if
                showQueue(headPtr);
                break;
            default:
                printf("Invalid choice.\n");
                showMenu();
                break;
        }
        showMenu();
        printf("? ");
        scanf("%u", &ch);
    }
    printf("Thank You!\n");
    return 0;
}

// Display Menu Function
void showMenu(void) {
    printf("Enter your choice:\n"
        "   1 to enqueue element into the queue.\n"
        "   2 to dequeue element from the queue.\n"
        "   3 to end" );
}

// insert a new value into the queue
void enqueue(QueueNodePtr *headPtr, QueueNodePtr *tailPtr, char value) {
    QueueNodePtr newPtr; // pointer to new node
    newPtr = malloc(sizeof(QueueNode)); // Create a node
    
    // if allocated
    if (newPtr != NULL) {
        newPtr->data = value;   // put value in the node
        newPtr->nextPtr = NULL;
        
        // if empty, insert node to head 
        if (isEmpty(*headPtr)) {
          *headPtr = newPtr;
        } 
        else {
          // assign nextPtr of tail node to the address of newPtr
          (*tailPtr)->nextPtr = newPtr;
        }
        *tailPtr = newPtr; // finally point the tail to the newPtr
    }
    else {
        printf("%c is not inserted. \n", value);
    }
}

// dequeue a queue element
char dequeue(QueueNodePtr *headPtr, QueueNodePtr *tailPtr) {
    char item; // value of the node
    QueueNodePtr tmpPtr; // temporary node pointer

    item = (*headPtr)->data;
    tmpPtr = *headPtr;
    *headPtr = (*headPtr)->nextPtr;

    // if queue is empty 
    if(*headPtr == NULL) {
      *tailPtr = NULL;
    }

    free(tmpPtr);
    return item;

    
}

// return 1 if the queue is empty, otherwise 0
int isEmpty(QueueNodePtr headPtr) {
    return headPtr == NULL;
}

// show the queue
void showQueue(QueueNodePtr currentPtr) {
    // if queue is empty
    if (isEmpty(currentPtr)) {
        printf("The queue is empty!\n");
    }
    else {
        printf("The queue is: \n");
        
        // while not the end of list
        while(currentPtr != NULL) {
            printf("%c ==> ", currentPtr->data);
            currentPtr = currentPtr->nextPtr;
        }
        printf("NULL\n");
    }
}

Firstly, we have to understand the operation of the queue. A queue has a head and a tail from which data are dequeued and enqueued respectively. So, let’s look at the enqueue operation:

QueueNodePtr newPtr; // pointer to new node
newPtr = malloc(sizeof(QueueNode)); // Create a node

The above lines of code allocates required memory for a new node in the queue.

 // if allocated
    if (newPtr != NULL) {
        newPtr->data = value;   // put value in the node
        newPtr->nextPtr = NULL;
        
        // if empty, insert node to head 
        if (isEmpty(*headPtr)) {
          *headPtr = newPtr;
        } 
        else {
          // assign nextPtr of tail node to the address of newPtr
          (*tailPtr)->nextPtr = newPtr;
        }
        *tailPtr = newPtr; // finally point the tail to the newPtr
    }

In the above lines of code, we assigned the entered value to the data of new node and the nextPtr to NULL. Let’s suppose, the queue is empty, then we have to point the head to the newPtr, otherwise, to the nextPtr of the tailPtr.

Similarly, let’s view the code for the dequeue operation.

// dequeue a queue element
char dequeue(QueueNodePtr *headPtr, QueueNodePtr *tailPtr) {
    char item; // value of the node
    QueueNodePtr tmpPtr; // temporary node pointer

    item = (*headPtr)->data;
    tmpPtr = *headPtr;
    *headPtr = (*headPtr)->nextPtr;

    // if queue is empty 
    if(*headPtr == NULL) {
      *tailPtr = NULL;
    }

    free(tmpPtr);
    return item;
}

Here, we just removed the data from the head and point to the nextPtr. Importantly, we have freed the memory.

In this way, we implement a queue in C as shown in the example above. Lastly, if you want to view the code, you can find it in the gist here.

If you like to learn about Rest API in Django, you can click here: https://nepcodex.com/2019/07/django-rest-api-from-scratch-part-1/

Also, if you want a boilerplate to start a project in React, Redux and Router, you can visit this link here: https://nepcodex.com/2019/07/a-guide-to-react-redux-router-latest-version/

I am a Computer Engineer from Pulchowk Campus, IOE. I love programming, and music. Python, Java, Php, Javascript, Django, Laravel, Spring, express.js, etc. are my specialities.

Leave a Reply

%d bloggers like this: