总结归纳
- 队列实际上就是现实生活中的排队,队头的人先走,新来的人排到队尾。先进先出,后进后出。
- 队列的实现,需要一个队头指针,一个队尾指针,用于入队和出队。对于循环队列,初始化时需将 Q.front = Q.rear = 0,Q.front 指向队头,Q.rear 指向新元素入队的位置。
- 循环队列,物理上仍然是申请一片连续的内存空间,但通过 (Q.rear + 1) % MaxSize == Q.front 的判断条件从逻辑上模拟环状空间,从而实现循环队列。
- 代码中值得一提的是 GetLength(SqQuene &Q, ElemType &len) 函数(获取队列长度),当有元素出队时,实际上只是将 Q.front 前移,从逻辑上出队,原先的队头仍然存在,当下次有新元素入队时直接进行覆盖,所以长度的遍历应从 Q.front 开始;而在队列的初始化中,我们设置的是 Q.front = Q.rear = 0 ,例如:当队列中有一个元素时,Q.front = 0,而 length = 1,所以我们需要将这个 1 补回来,才是真正的队列长度。
- 以往的 GetLength 代码,总是通过指针来进行遍历,而循环队列能不能用指针获取长度,我的看法是不可以(如果可以麻烦告诉我)。之前的数据结构能用指针遍历,是因为 struct 结构体中就定义了指针,所以可以申请一个结构体指针指向该结构体,通过 p = p->next 来进行遍历;而循环队列的实质仍然是一片连续的内存空间,诚然你可以申请一个数组指针 int *p = Q.data,但又回到了刚才的问题:在已有元素出队的情况下,Q.data 的第一个元素就不是队头,这会影响到队列长度的判断。而对于链式数据结构,删了就是删了,直接 delete / free ,就没有这个问题。
bool GetLength(SqQuene &Q, ElemType &len) {
if (Q.front == Q.rear) {
len = 0;
} else {
len = Q.front;
while ((len + 1) % MaxSize != Q.rear) {
len++;
}
len = len - Q.front + 1;
}
return true;
}
代码实现
#include <iostream>
#define MaxSize 10
using namespace std;
typedef int ElemType;
struct SqQueue {
ElemType data[MaxSize];
int front, rear;
};
void InitQueue(SqQueue &Q) { Q.front = Q.rear = 0; }
bool QueueEmpty(SqQueue &Q) {
if (Q.front == Q.rear) {
return true;
} else {
return false;
}
}
bool EnQueue(SqQueue &Q, ElemType x) {
if ((Q.rear + 1) % MaxSize == Q.front) {
return false;
} else {
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) %
MaxSize;
return true;
}
}
bool DeQueue(SqQueue &Q, ElemType &x) {
if (Q.rear == Q.front) {
return false;
} else {
x = Q.data[Q.front];
Q.front = (Q.front + 1) % MaxSize;
return true;
}
}
bool GetHead(SqQueue &Q, ElemType &x) {
if (Q.rear == Q.front) {
return false;
} else {
x = Q.data[Q.front];
return true;
}
}
bool GetLength(SqQueue &Q, ElemType &len) {
if (Q.front == Q.rear) {
len = 0;
} else {
len = Q.front;
while ((len + 1) % MaxSize != Q.rear) {
len++;
}
len = len - Q.front + 1;
}
return true;
}
int main() {
SqQueue Q;
InitQueue(Q);
ElemType head, pop, length;
for (int i = 1; i < 6; i++) {
EnQueue(Q, i);
}
GetHead(Q, head);
cout << "队头元素:" << head << endl;
GetLength(Q, length);
cout << "队列长度:" << length << endl;
DeQueue(Q, pop);
cout << "出队元素:" << pop << endl;
GetHead(Q, head);
cout << "队头元素:" << head << endl;
GetLength(Q, length);
cout << "队列长度:" << length << endl;
}