Queue - simple operation of chain queue and sequential queue

Keywords: C data structure linked list

Queue learning notes – chain team and sequence team

1. Queue (circular queue)

In the sequential storage structure of the queue, in addition to using a group of storage units with continuous addresses to store the elements from the queue head to the queue tail in turn, it is also necessary to attach two integer variable front and rear to indicate the positions of the queue head element and the queue tail element respectively (hereinafter referred to as head pointer and tail pointer respectively).

Whenever a new queue tail element is inserted, the tail pointer real increases by 1; Whenever the queue header element is deleted, the header pointer front is incremented by 1. Therefore, in a non empty queue, the head pointer always points to the queue head element and the tail pointer always points to the next position of the queue tail element.

The circular queue can make full use of space and reduce the time complexity by moving frong and rear.

How to judge whether the team is full or empty:
One less element space is used, that is, when the queue space is m, m-1 elements are considered to be full. In this way, the condition for judging the empty queue is that when the values of the head and tail pointers are the same, the empty queue is considered; When the tail pointer is equal to the head pointer after adding 1 in the cyclic sense, it is considered that the team is full.

All codes are as follows

//Sequential queue general operations
#include<stdio.h>
#include<stdlib.h>
#define MAXQSIZE 10 / / the maximum possible length of the queue
typedef int QElemType;           //The element type is an integer
typedef struct {
    QElemType data[MAXQSIZE];    //Define an array to hold data
    int front;                   //number one
    int rear;                    //last digits of a number 
} sqQueue;

sqQueue *QueueCreate() {
    sqQueue *q = (sqQueue *)malloc(sizeof(sqQueue));                    //Allocate space, take base address
    q->front = q->rear = 0;
    printf("Initialization complete!\n");
    return q;
}
//Find the queue length (circular queue)
void QueueLength(sqQueue *q) {
    printf("Queue length:%d\n",(q->rear-q->front+MAXQSIZE) % MAXQSIZE);    //The tail number may be larger than the number one, so pay attention to the calculation of length
}
//Join the team
void EnterQueue(sqQueue *q, QElemType a) {
    if ((q->rear + 1) % MAXQSIZE == q->front) {
        printf("The team is full!\n");
    }
    else {
        q->data[q->rear] = a;
        q->rear = (q->rear + 1) % MAXQSIZE;
    }
}
//Out of the team
void ExitQueue(sqQueue *q) {
    if (q->front == q->rear) {
        printf("Team empty!");
    }
    else {
        printf("Outgoing element:%d\n", q->data[q->front]);
        q -> front = (q->front + 1) % MAXQSIZE;
    }
}
//Print queue
void PrintQueue(sqQueue *q) {
    int t = q->front;
    while (q->front != q->rear) {
        printf("%d ", q->data[t]);
        ++t;
        t %= MAXQSIZE;
        if (t == q->rear) {
            printf("\n");
            break;
        }
    }
}
int main() {
    sqQueue *q;
    int le;
    q = QueueCreate();              //initialization
    for (int i = 1; i < 6; ++i) {
        EnterQueue(q, i);           //Join the team from 1 to 5
    }
    PrintQueue(q);                  //Print and display
    ExitQueue(q);                   //Out of pair, delete the team head element
    QueueLength(q);                 //Output queue length
    ExitQueue(q);
    QueueLength(q);
    PrintQueue(q);
    EnterQueue(q, 10);
    EnterQueue(q, 20);              //Two elements of reentry team 10, 20
    PrintQueue(q);                  //Output look
    return 0;
}

2. Chain team

A chain team obviously needs two pointers indicating the head and tail of the team (called head pointer and tail pointer respectively) to be uniquely determined.

The operation of chain queue is a special case of single linked list insertion and deletion, but the tail pointer or head pointer needs to be further modified. The chain team is only inserted at the head of the list and deleted at the end of the list.
When the chain queue goes out of the queue, it should also be considered that when the last element in the queue is deleted, the pointer at the end of the queue will also be lost
Lost, so it is necessary to re assign the pointer at the end of the queue (pointing to the head node).

Chained storage structure of queue:
This is somewhat different from the single linked list, which has more head pointers and tail pointers, while the single linked list has only head nodes or head pointers

typedef int QElemType;
typedef struct QueueNode {
    QElemType data;                     //data type
    struct QueueNode *next;             //Next node
} Queuenode, *QueuePtr;

typedef struct {
    QueuePtr front; //Head pointer
    QueuePtr rear;  //Tail pointer
} LinkQueue;

All codes are as follows:

//Chain stack queue general operation
#include<stdio.h>
#include<stdlib.h>
#define N 10
typedef int QElemType;
typedef struct QueueNode {
    QElemType data;                     //data type
    struct QueueNode *next;             //Next node
} Queuenode, *QueuePtr;

typedef struct {
    QueuePtr front; //Head pointer
    QueuePtr rear;  //Tail pointer
} LinkQueue;

//Initialize and create a queue of header nodes
LinkQueue CreateQueuelist(LinkQueue Q) {
    QueuePtr L = (QueuePtr)malloc(sizeof(Queuenode));       //Create header node
    Q.front = Q.rear = L;                                   // The head and tail pointers point to this node
    Q.front->next = NULL;                                   //Null header pointer field
    return Q;
}

/* //Join the team
Queuenode *EntQueuelist(LinkQueue Q, QElemType a) {
    QueuePtr temp = (QueuePtr)malloc(sizeof(Queuenode));    //Allocate node space for the queued elements and point to it with the pointer temp
    temp->data = a;                                         //Set the new node data field to e
    temp->next = NULL;                                      //Null pointer field                   
    Q.rear->next = temp;                                    //Insert a new node at the end of the queue
    Q.rear = temp;                                          //Modify the end of queue pointer to remp   
    return Q.rear;                                          //Here you have to return Q.next, otherwise the linked list always has only the latest element in the queue
}  */                                                       //Because Q.rear is a local pointer variable, it will return to the initialized value after returning, so that every time it is queued, it is only a new element, and the previous one is gone

//You can also take the following to return Q. The reason is the same as above
LinkQueue EntQueuelist(LinkQueue Q, QElemType a) {
    QueuePtr temp = (QueuePtr)malloc(sizeof(Queuenode));    //Allocate node space for the queued elements and point to it with the pointer temp
    temp->data = a;                                         //Set the new node data field to e
    temp->next = NULL;                                      //Null pointer field                   
    Q.rear->next = temp;                                    //Insert a new node at the end of the queue
    Q.rear = temp;                                          //Modify the end of queue pointer to remp   
    return Q;                                               
}  

//Out of the team
void ExtQueuelist(LinkQueue Q) {
    if (Q.front == Q.rear) {                                //Determine whether the queue is empty
        printf("Empty queue!\n");
    }
    else {
        QueuePtr temp;
        temp = Q.front->next;                               //Temporarily save the space of the queue header element for release.
        Q.front->next = temp->next;
        printf("Outgoing element:%d\n", temp->data);
        if (Q.rear == temp) {                               //Judge whether the queue element is the last element. If so, re assign the tail pointer to the head node.
            Q.rear = Q.front;
        }
        free(temp);                                         //Free up space for the original team head element
    }
}

//Print queue
void PrintQueue(LinkQueue Q) {
    QueuePtr h;
    h = Q.front->next;
    if (h == NULL) {
        printf("Empty linked list\n");
    }
    while (h) {
        printf("%d ", h->data);
        h = h->next;
    }
    printf("\n");
}

int main() {
    LinkQueue Q;
    Q = CreateQueuelist(Q);
    for (int i = 0; i < 6; ++i) {                           //Recycling queue assignment
        // Q.rear = EntQueuelist(Q, i+1);
        Q = EntQueuelist(Q, i+1);    
    }
    PrintQueue(Q);                                          //Print the elements of the linked list at this time  
    ExtQueuelist(Q);                                        //The first element of the queue, that is, the first element of the linked list
    Q = EntQueuelist(Q, 100);
    // Q.rear = EntQueuelist(Q, 100);
    ExtQueuelist(Q);
    PrintQueue(Q);
    return 0;
}

Posted by dragin33 on Sat, 04 Dec 2021 18:46:25 -0800