Data Structure-Cyclic Queue (C Language)
To learn circular queues, first understand the queues.A queue is a first-in-first-out linear table that allows insertion only at one segment of the table and deletion of elements at the other end.The end allowed to insert in the queue is the end of the queue, and the end allowed to delete is the front.
A circular queue appears to solve the problem of false overflow in a sequential queue.False overflow is that in a sequential queue, the tail pointer has reached the upper bound of the array and cannot be inserted anymore, and there is still an empty position in the queue.
Circular queues also have the problem of not being able to tell if they are full.There are two main solutions.
1. Set another flag to distinguish if the queue is full.
2. Use less element space.Contract that the queue head pointer will be full when it is next to the queue end pointer.(The following options take this approach)
Circular Queue Diagram
There are two basic judgments:
Judging that the queue is empty: q.front==q.rear means that the direction of the head and tail pointers are the same
Judging that the queue is full: (q.rear+1)%maxsize==q.front
Where maxsize is the capacity of the queue, q.front is the head pointer, and q.rear is the tail pointer.
The following are basic operations about the definition, initialization, queuing, queuing, and finding the queue length of a circular queue.
Definition
typedef struct { int* base; //Benchmark location for opening up space int front; //Queue Head Pointer int rear; //End of Queue Pointer }reQueue;
Initialization
int init_REQUEUE(reQueue& q) { q.base=(int*)malloc(sizeof(int)*maxsize); if(!q.base) return 0; q.front=q.rear=0; return 1; }
Note: When initializing, the values of q.front and q.rear are 0.
Entry
int in_REQUEUE(reQueue& q,int e) { if((q.rear+1)%maxsizei==q.front) return 0; *(q.base+q.rear)=e; q.rear=(q.rear+1)%maxsize; return 1; }
The first step is to determine whether the circular queue is full or not. If it is full, the queue cannot be enlisted, otherwise the queue operation will be performed.
The second step is to store the queued elements in the tail pointer position.
Step 3, move the tail pointer one bit backward.
Queue
int de_REQUEUE(reQueue& q,int& e) { if(q.front==q.rear) return 0; e=*(q.base+q.front); q.front=(q.front+1)%REQUEUE_SIZE; return 1; }
The first step is to determine if the circular queue is empty. If it is empty, the queue cannot be queued. Otherwise, the queue operation will be performed.
The second step assigns the outgoing elements to e.
Step 3, move the head pointer one place back.
Find Queue Length
int le_REQUEUE(reQueue q) { return (q.rear-q.front+maxsize)%maxsize; }
Program code:
#include<stdio.h> #include<stdlib.h> #define maxsize 5 //Define a circular queue capacity of 5 typedef struct { int* base; int front; int rear; }reQueue; int init_REQUEUE(reQueue& q) { q.base=(int*)malloc(sizeof(int)*maxsize); if(!q.base) return 0; q.front=q.rear=0; return 1; } int in_REQUEUE(reQueue& q,int e) { if((q.rear+1)%maxsize==q.front) return 0; *(q.base+q.rear)=e; q.rear=(q.rear+1)%maxsize; return 1; } int de_REQUEUE(reQueue& q,int& e) { if(q.front==q.rear) return 0; e=*(q.base+q.front); q.front=(q.front+1)%maxsize; return 1; } int le_REQUEUE(reQueue q) { return (q.rear-q.front+maxsize)%maxsize; } void tra_REQUEUE(reQueue q) { if(q.front==q.rear) return; for(int i=0;i<le_REQUEUE(q);i++){ printf("%d ",*(q.base+(q.front+i)%maxsize)); } printf("\n"); } int main() { reQueue q; int e; //Initialize circular queue init_REQUEUE(q); //Entry 1 2 3 in_REQUEUE(q,1); in_REQUEUE(q,2); in_REQUEUE(q,3); tra_REQUEUE(q); //Queue de_REQUEUE(q,e); printf("%d\n",le_REQUEUE(q)); //Queue de_REQUEUE(q,e); printf("%d\n",e); //Entry in_REQUEUE(q,3); in_REQUEUE(q,3); in_REQUEUE(q,3); in_REQUEUE(q,3); in_REQUEUE(q,3); in_REQUEUE(q,3); tra_REQUEUE(q); printf("%d\n",le_REQUEUE(q)); return 0; }