Summary
- A queue is actually a queue in real life. The people at the head of the queue go first and the newcomers line up at the end of the queue. First in, first out, last in, last out.
- The implementation of queue requires a team head pointer and a team tail pointer for entering and leaving the team. For circular queues, during initialization, Q.front = Q.rear = 0, Q.front points to the queue head, and Q.rear points to the queue entry position of new elements.
- The circular queue still applies for a continuous memory space physically, but logically simulates the circular space through the judgment condition of (q.rear + 1)% maxsize = = q.front, so as to realize the circular queue.
- The getlength (sqqueue & Q, ElemType & len) function is worth mentioning in the code (get the queue length). When an element leaves the queue, it actually just moves the Q.front forward and logically leaves the queue. The original queue head still exists. When a new element enters the queue next time, it will be overwritten directly, so the traversal of the length should start from Q.front; in the initialization of the queue, we set Q.front = Q.rear = 0, for example, when there is an element in the queue, Q.front = 0 and length = 1, so we need to make up this 1, which is the real queue length.
- In the past, GetLength codes always traverse through pointers. Can circular queues obtain the length with pointers, I don't think so (please tell me if you can). The previous data structures can be traversed with pointers because pointers are defined in the struct structure, so you can apply for a structure pointer to point to the structure and traverse it through P = P - > next. The essence of the circular queue is still a continuous memory space. Admittedly, you can apply for an array pointer int *p = Q.data, but Back to the question just now: when the existing elements are out of the queue, the first element of Q.data is not the queue head, which will affect the judgment of queue length. For linked data structures, deleting is deleting. If you directly delete / free, there is no such problem.
// Get queue length
bool GetLength(SqQuene &Q, ElemType &len) {
if (Q.front == Q.rear) {
len = 0;
} else {
len = Q.front; // Point to the head of the team
while ((len + 1) % MaxSize != Q.rear) {
len++;
}
len = len - Q.front + 1; // If there are elements out of the queue, the Q.front will not be 0, which will affect the judgment of length. When initializing the queue, the Q.front will be set to 0, which will also affect the length
}
return true;
}
code implementation
/*
Circular queue
*/
#include <iostream>
#define MaxSize 10 / / the maximum number of elements in the queue
using namespace std;
typedef int ElemType;
struct SqQuene {
ElemType data[MaxSize]; // Maximum number of elements in the queue
int front, rear; // Queue head pointer
};
// Initialize queue
void InitQuene(SqQuene &Q) { Q.front = Q.rear = 0; }
// Queue empty
bool QueneEmpty(SqQuene &Q) {
if (Q.front == Q.rear) {
return true;
} else {
return false;
}
}
// Join the team
bool EnQuene(SqQuene &Q, ElemType x) {
if ((Q.rear + 1) % MaxSize == Q.front) { // Team full
return false;
} else {
Q.data[Q.rear] = x; // Assign to the next team tail
Q.rear = (Q.rear + 1) %
MaxSize; // Logically, the storage space becomes a "ring", which is still a static array physically
return true;
}
}
// Out of the team
bool DeQuene(SqQuene &Q, ElemType &x) {
if (Q.rear == Q.front) { // Team air
return false;
} else {
x = Q.data[Q.front];
Q.front = (Q.front + 1) % MaxSize; // The queue head pointer moves back
return true;
}
}
// Get queue header element
bool GetHead(SqQuene &Q, ElemType &x) {
if (Q.rear == Q.front) { // Team air
return false;
} else {
x = Q.data[Q.front];
return true;
}
}
// Get queue length
bool GetLength(SqQuene &Q, ElemType &len) {
if (Q.front == Q.rear) {
len = 0;
} else {
len = Q.front; // Point to the head of the team
while ((len + 1) % MaxSize != Q.rear) {
len++;
}
len = len - Q.front + 1; // If there are elements out of the queue, the Q.front will not be 0, which will affect the judgment of length. When initializing the queue, the Q.front will be set to 0, which will also affect the length
}
return true;
}
int main() {
SqQuene Q;
InitQuene(Q);
ElemType head, pop, length;
for (int i = 1; i < 6; i++) {
EnQuene(Q, i);
}
GetHead(Q, head);
cout << "Team head element:" << head << endl;
GetLength(Q, length);
cout << "Queue length:" << length << endl;
DeQuene(Q, pop);
cout << "Outgoing element:" << pop << endl;
GetHead(Q, head);
cout << "Team head element:" << head << endl;
GetLength(Q, length);
cout << "Queue length:" << length << endl;
}