C Queue Implementation: Code and Explanation

C Queue Implementation

This document details the implementation of a queue data structure in C. It includes the code and explanations for various queue operations.

Queue Structure Definition


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

struct queue {
    int size;
    int capacity;
    int* data;
    int front;
    int back;
};

typedef struct queue Queue;

Queue Initialization

The queue_init_default function initializes a new queue with a default capacity of 10.


QUEUE queue_init_default(void) {
    Queue* pQueue;
    pQueue = (Queue*)malloc(sizeof(Queue));

    if (pQueue != NULL) {
        pQueue->capacity = 10;
        pQueue->size = 0;
        pQueue->front = -1; // better to not be zero
        pQueue->back = 0;
        pQueue->data = (int*)malloc(sizeof(int) * pQueue->capacity);

        if (pQueue->data == NULL) {
            printf("Object is half created\n");
            free(pQueue);
            pQueue = NULL;
        }
    }
    return pQueue;
}

Enqueue Operation

The queue_enquene function adds an item to the back of the queue. If the queue is full, it doubles the capacity.


Status queue_enquene(QUEUE hQueue, int item) {
    int* temp; int i;
    Queue* pQueue = (Queue*)hQueue;

    // If there's not enough room
    if (pQueue->size >= pQueue->capacity) {
        temp = (int*)malloc(sizeof(int) * pQueue->capacity * 2);
        if (temp == NULL) {
            return FAILURE;
        }

        for (i = 0; i < pQueue->size; i++) {
            temp[i] = pQueue->data[(pQueue->front + i) % pQueue->capacity];
        }

        pQueue->front = 0;
        pQueue->back = pQueue->size;
        pQueue->capacity *= 2;
        free(pQueue->data); // free first then point to temp
        pQueue->data = temp;
    }

    // if there is room then do the below
    pQueue->data[pQueue->back] = item; // to add the final item in the back
    pQueue->back = (pQueue->back + 1) % pQueue->capacity;
    pQueue->size++;

    if (pQueue->front == -1) {
        pQueue->front = 0;
    }
    return SUCCESS;
}

Dequeue Operation

The queue_service function removes the item at the front of the queue.


Status queue_service(QUEUE hQueue) {
    Queue* pQueue = (Queue*)hQueue;

    if (pQueue->size == 0) {
        return FAILURE;
    }

    pQueue->front = (pQueue->front + 1) % pQueue->capacity;
    pQueue->size--;
    return SUCCESS;
}

Front Operation

The queue_front function returns the item at the front of the queue without removing it.


int queue_front(QUEUE hQueue, Status* pStatus) {
    Queue* pQueue = (Queue*)hQueue; // cast to the known type

    if (pQueue->size == 0) { // if there's nothing stored in pqueue than fail
        if (pStatus != NULL) {
            *pStatus = FAILURE;
        }
        return INT_MIN;
    }

    if (pStatus != NULL) {
        *pStatus = SUCCESS;
    }
    return pQueue->data[pQueue->front];
}

Size Operation

The queue_size function returns the number of items in the queue.


int queue_size(QUEUE hQueue) {
    Queue* pQueue = (Queue*)hQueue;
    return pQueue->size;
}

Empty Operation

The queue_empty function checks if the queue is empty.


Boolean queue_empty(QUEUE hQueue) {
    Queue* pQueue = (Queue*)hQueue;
    return (Boolean)(pQueue->size == 0); // just for reader does nothing
}

Destroy Operation

The queue_destroy function deallocates the memory used by the queue.


void queue_destroy(QUEUE* phQueue) {
    Queue* pQueue = (Queue*)*phQueue; // just for reader
    free(pQueue->data);
    free(pQueue);
    *phQueue = NULL;
    return;
}