Skip to main content

Data Structures 09 - Linked Queue

Code

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

/**
* Node structure definition for a linked queue.
*/
typedef struct LinkNode{
int data;
struct LinkNode* next;
}*LinkNodePtr;

/**
* Linked queue structure definition.
*/
typedef struct LinkQueue{
LinkNodePtr front;
LinkNodePtr rear;
}*LinkQueuePtr;

/**
* Initialize an empty queue.
*/
LinkQueuePtr initQueue(){
LinkQueuePtr resultPtr = (LinkQueuePtr)malloc(sizeof(struct LinkQueue));
// Create a head node; its data is not important.
LinkNodePtr headerPtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
headerPtr->next = NULL;

resultPtr->front = headerPtr;
resultPtr->rear = headerPtr;
return resultPtr;
}// End of initQueue

/**
* Output the elements in the queue.
*/
void outputLinkQueue(LinkQueuePtr paraQueuePtr){
LinkNodePtr tempPtr = paraQueuePtr->front->next;
while (tempPtr != NULL) {
printf("%d ", tempPtr->data);
tempPtr = tempPtr->next;
}// End of while loop
printf("\r\n");
}// End of outputLinkQueue

/**
* Enqueue operation.
*/
void enqueue(LinkQueuePtr paraQueuePtr, int paraElement) {
// Step 1: Create a new node
LinkNodePtr tempNodePtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
tempNodePtr->data = paraElement;
tempNodePtr->next = NULL;

// Step 2: Link the new node to the end of the existing queue
paraQueuePtr->rear->next = tempNodePtr;

// Step 3: The new node becomes the new rear
paraQueuePtr->rear = tempNodePtr;
}// End of enqueue

/**
* Dequeue operation.
* @return The value of the front element
*/
int dequeue(LinkQueuePtr paraQueuePtr) {
int resultValue;
LinkNodePtr tempNodePtr;

// Step 1: Check if the queue is empty
if (paraQueuePtr->front == paraQueuePtr->rear) {
printf("Queue is empty.\r\n");
return -1;
}// End of if

// Step 2: Modify the queue structure
tempNodePtr = paraQueuePtr->front->next;
resultValue = tempNodePtr->data;
paraQueuePtr->front->next = paraQueuePtr->front->next->next;

if (paraQueuePtr->rear == tempNodePtr) {
paraQueuePtr->rear = paraQueuePtr->front;
}// End of if

// Step 3: Free space
// free(tempNodePtr);
tempNodePtr = NULL;

// Step 4: Return the result
return resultValue;
}// End of dequeue

/**
* Unit test function.
*/
void testLinkQueue(){
LinkQueuePtr tempQueuePtr;
tempQueuePtr = initQueue();
enqueue(tempQueuePtr, 10);
enqueue(tempQueuePtr, 30);
enqueue(tempQueuePtr, 50);

outputLinkQueue(tempQueuePtr);

printf("Dequeued %d\r\n", dequeue(tempQueuePtr));
printf("Dequeued %d\r\n", dequeue(tempQueuePtr));
printf("Dequeued %d\r\n", dequeue(tempQueuePtr));
printf("Dequeued %d\r\n", dequeue(tempQueuePtr));

enqueue(tempQueuePtr, 8);
outputLinkQueue(tempQueuePtr);
}// End of testLinkQueue

/**
* Main function.
*/
int main(){
testLinkQueue();
return 1;
}// End of main

Code Summary: This code is an implementation of a linked queue, including queue initialization, enqueue, dequeue, and output queue element functions. Below is a detailed explanation of each part:

  1. Header files and structure definitions:

    • #include <stdio.h> and #include <malloc.h> include the standard I/O library and memory allocation library.
    • typedef struct LinkNode defines the node structure for the linked queue, containing an integer data data and a pointer to the next node next.
    • typedef struct LinkQueue defines the linked queue structure, containing pointers to the queue front and rear front and rear.
  2. initQueue function:

    • Creates an empty linked queue, allocating memory for the queue structure and head node.
    • The head node's data is not used; it only serves as the start of the queue, and its next pointer is initially NULL.
    • Both the front and rear pointers of the queue point to the head node.
  3. outputLinkQueue function:

    • Traverses the queue, starting from the node after the head node, until it encounters NULL, outputting each node's data.
  4. enqueue function:

    • Creates a new node, places the data into the node, and sets the next pointer to NULL.
    • Links the new node to the end of the queue and updates the queue's rear pointer to point to the new node.
  5. dequeue function:

    • Checks if the queue is empty; if empty, outputs an error message and returns -1.
    • Removes a node from the front of the queue, gets and returns that node's data.
    • Updates the queue's front pointer; if the removed node is the only node in the queue, the rear pointer also needs to be updated.
    • Frees the memory of the removed node and sets the pointer to NULL.
  6. testLinkQueue function:

    • Initializes a queue, performs enqueue operations, then outputs the queue contents.
    • Performs dequeue operations, outputting the value each time.
    • Performs enqueue operations again and outputs the queue contents.
  7. main function:

    • Calls the testLinkQueue function to run unit tests; this is the program entry point.

The entire code implements the basic operations of a linked queue and demonstrates how to use these functions to operate the queue through the testLinkQueue unit test function.

Running Result