This problem needs to implement a circular queue, so before that, we need to know the concept and structure of queue
Queue: a special linear table that can only be inserted at one end and deleted at the other end. It has the characteristics of first in first out, then in and then out
Delete one end of the queue
Enter the queue: the end of the insertion is called the end of the queue
Knowing the concept and structure of queue, you can start to do this problem.
Title Link
Title Description:
Idea: first, find the condition that the queue is empty and the condition that the queue is full. It is easy to find these two conditions. I give the condition that the queue is empty. When the head and tail of the queue are equal, it means that the queue is empty. If the queue is full, the queue will be full when it is equal to the next one at the end of the queue. Careful friends may have seen it here. In this case, don't you need one less data? It's true. But in order to solve this problem, I decided to use the last space of the queue as the end condition, but I don't want to lose one of the transmitted data, so I directly opened an additional space to judge the end when I created it, which perfectly solves the problem that there is a lot of data and can judge whether the queue is full
First, we need a circular queue structure. I define it as follows:
typedef struct { int* a; int k;//Total queue size int front;//Team leader int tail;//Team tail } MyCircularQueue;
It looks like this:
Let's implement an initialization function MyCircularQueue* myCircularQueueCreate(int k);
MyCircularQueue* myCircularQueueCreate(int k) { //A queue MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue)); //Initialize queue //One more space should be opened here to judge whether the queue is full obj->a = (int*)malloc(sizeof(int) * (k + 1)); obj->front = 0; obj->tail = 0; obj->k = k; //Returns the address of the queue return obj; }
After implementing the above function, we begin to implement a function bool mycircularqueue isempty (mycircularqueue * obj) to judge whether the queue is empty; And the function bool myCircularQueueIsFull(MyCircularQueue* obj) to judge whether the queue is full;
bool myCircularQueueIsEmpty(MyCircularQueue* obj) { //If front and tail are equal, it means they are empty return obj->front == obj->tail; } bool myCircularQueueIsFull(MyCircularQueue* obj) { //The next coordinate of the tail of the team is given to tailNext; int tailNext = obj->tail + 1; //If it is equal to the coordinates of the last space, the queue is full at this time if (tailNext == obj->k + 1) { //Set it as the coordinates of the head tailNext = 0; } return tailNext == obj->front; }
With these two functions, we can start to implement the queue insertion function
According to the above steps, we can quickly implement the insertion function
bool myCircularQueueEnQueue( MyCircularQueue* obj, int value) { //Judge whether it is full. If it is full, do not insert it if (myCircularQueueIsFull(obj)) { return false; } else { //Insert it into the tail position and increase it automatically obj->a[obj->tail] = value; obj->tail++; //It is used to prevent cross-border. When tail is greater than k, it is set to 0 to complete the circular queue obj->tail %= (obj->k + 1); return true; } }
Since the delete function of the delete queue is similar to the insert function, I won't repeat it one by one here. I believe you understand the logic of the insert, and the deletion should be very simple.
All codes:
typedef struct { int* a; int k;//Total queue size int front;//Team leader int tail;//Team tail } MyCircularQueue; MyCircularQueue* myCircularQueueCreate(int k) { //A queue MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue)); //Initialize queue //One more space should be opened here to judge whether the queue is full obj->a = (int*)malloc(sizeof(int) * (k + 1)); obj->front = 0; obj->tail = 0; obj->k = k; //Returns the address of the queue return obj; } bool myCircularQueueIsEmpty(MyCircularQueue* obj) { //If front and tail are equal, it means they are empty return obj->front == obj->tail; } bool myCircularQueueIsFull(MyCircularQueue* obj) { //The next coordinate of the tail of the team is given to tailNext; int tailNext = obj->tail + 1; //If it is equal to the coordinates of the last space, the queue is full at this time if (tailNext == obj->k + 1) { //Set it as the coordinates of the head tailNext = 0; } return tailNext == obj->front; } bool myCircularQueueEnQueue( MyCircularQueue* obj, int value) { //Judge whether it is full. If it is full, do not insert it if (myCircularQueueIsFull(obj)) { return false; } else { //Insert it into the tail position and increase it automatically obj->a[obj->tail] = value; obj->tail++; //It is used to prevent cross-border. When tail is greater than k, it is set to 0 to complete the circular queue obj->tail %= (obj->k + 1); return true; } } bool myCircularQueueDeQueue(MyCircularQueue* obj) { if ( myCircularQueueIsEmpty(obj)) { return false; } else { //Each self increment of header is equivalent to the data of one queue obj->front++; //It is used to prevent cross-border. When the front is greater than k, it is set to 0 to complete the circular queue obj->front %= (obj->k + 1); return true; } } int myCircularQueueFront(MyCircularQueue* obj) { //Judge whether it is empty. If it is empty, return - 1 if (myCircularQueueIsEmpty(obj)) { return -1; } else//If it is not empty, return the header data { return obj->a[obj->front]; } } int myCircularQueueRear(MyCircularQueue* obj) { //If the queue is empty, - 1 is returned if (myCircularQueueIsEmpty(obj)) { return -1; } //tail is the previous and the last data int tailPrev = obj->tail - 1; //If tailPrev is equal to - 1, the tail at this time is 0 if (tailPrev == -1) { tailPrev = obj->k; } //Return the data of tailPrev return obj->a[tailPrev]; } void myCircularQueueFree(MyCircularQueue* obj) { //Release queue free(obj->a); free(obj); } /** * Your MyCircularQueue struct will be instantiated and called as such: * MyCircularQueue* obj = myCircularQueueCreate(k); * bool param_1 = myCircularQueueEnQueue(obj, value); * bool param_2 = myCircularQueueDeQueue(obj); * int param_3 = myCircularQueueFront(obj); * int param_4 = myCircularQueueRear(obj); * bool param_5 = myCircularQueueIsEmpty(obj); * bool param_6 = myCircularQueueIsFull(obj); * myCircularQueueFree(obj); */