#define MaxSize 10
typedef struct{
ElemType data[MaxSize];// 用静态数组存放队列元素
int front,rear;// 队头、队尾指针
}SqQueue;
void InitQueue(SqQueue &Q) {
Q.rear = Q.front = 0;// 初始时,队头】队尾指针都指向0
}
bool QueueEmpty(SqQueue Q) {
if(Q.rear == Q.front)// 队空条件
return true;
else return false;
}
bool EnQueue(SqQueue &Q,ElemType x) {
if((Q.rear + 1)%MaxSize == Q.front)// 队满条件
return false;
Q.data[rear] = x;
Q.rear = (Q.rear + 1)%MaxSize;// 队尾指针+1取模
return true;
}
思考1 队满条件是什么?
为什么要空一个位置呢?因为初始化时是Q.rear = Q.front = 0;为了与它区分,我们多空一个位置出来
思考2 Q.rear = (Q.rear + 1) mod MaxSize的原因,为什么不是Q.rear = Q.rear + 1?
如图,思考这个情况,当队尾指针指向MaxSize-1、队头指针指向元素d的位置时,此时想要入队的话,那队尾指针必须要重置回来,不然再Q.rear++的话就跑出数组范围了,那么怎么才能达到这样的效果呢?我们采用对MaxSize取模的操作,只要大于MaxSize了就会重置回来,用模运算将存储空间再逻辑上变成了“环状”
思考3 如何计算队列存在元素个数?
元素个数 = (Q.rear + MaxSize - Q.front)%MaxSize
bool DeQueue(SqQueue &Q,ElemType &x) {
if(Q.rear == Q.front) {
return false;
}
x = Q.data[Q.front];
Q.front = (Q.front + 1)%MaxSize;// 队头元素向后移动一位,取模原因如上
return true
}
bool QueueEmpty(SqQueue Q,ElemType &x) {
if(Q.rear == Q.front) {// 队空
return false;
}
x = Q.data[Q.front];
return true;
}
// 定义
typedef struct {
ElemType data[MaxSize];
int front,rear;
int size;// 记录大小长度
}SqQueue;
// 初始化
void InitQueue(SqQueue &Q) {
Q.rear = Q.front = 0;// 初始时,队头】队尾指针都指向0
size = 0;
}
// 入队操作
bool EnQueue(SqQueue &Q,ElemType x) {
if((Q.rear == Q.front && size == MaxSize)// 队满条件,这样就不浪费空间了
return false;
Q.data[rear] = x;
Q.rear = (Q.rear + 1)%MaxSize;// 队尾指针+1取模
size++;
return true;
}
// 出队操作
bool DeQueue(SqQueue &Q,ElemType &x) {
if(Q.rear == Q.front && size == 0) {// 队空条件
return false;
}
x = Q.data[Q.front];
Q.front = (Q.front + 1)%MaxSize;// 队头元素向后移动一位,取模原因如上
size--;
return true
}
//定义
typedef struct {
ElemType data[MaxSize];
int front,rear;
int tag;// 最近进行的是插入or删除
}SqQueue;
这两个的区别在于front指针指向的是头结点还是第一个元素
typedef struct LinkNode {// 链式队列结点
ElemType data;
struct LinkNode *next
}LinkNode;
typedef struct {// 链式队列
LinkNode *front,*rear;// 队列的队头和队尾指针
}LinkQueue;
typedef struct LinkNode {// 链式队列结点
ElemType data;
struct LinkNode *next
}LinkNode;
typedef struct {// 链式队列
LinkNode *front,*rear;// 队列的队头和队尾指针
}LinkQueue;
// 初始化
void InitQueue(LinkQueue &Q) {
// 初始时首尾指针都指向头结点
Q.rear = Q.front = (LinkNode *)malloc(sizeof(LinkNode));
Q.front = Null;
}
// 判断空
bool isEmpty(LinkQueue Q) {
if(Q.rear == Q.front) {
return true;
}else {
return true;
}
}
// 入队(新节点插入在队尾之后)
void EnQueue(LinkQueue &Q,ElemType x) {
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
s.data = x;
s.next = Null;
Q.rear->next = s;
Q.rear = s;
}
// 出队
bool DeQueue(LinkQueue &Q,ElemType &x) {
if(Q.front == Q.rear) {
return false;// 空队列
}else {
LinkNode *p = Q.front->next;
x = p->data;
Q.front = p->next;
if(Q.rear == p) {// 如果你删除的是最后一个结点的话
Q.rear = Q.front;// 需要修改队尾指针指向头结点
}
free(p);
return true;
}
}
// 初始化
void InitQueue(LinkQueue &Q) {
// 初始时首尾指针都指向Null
Q.rear = Q.front = Null;
}
// 判断空
bool isEmpty(LinkQueue Q) {
if(Q.rear == Null) {
return true;
}else {
return true;
}
}
// 入队(新节点插入在队尾之后)
void EnQueue(LinkQueue &Q,ElemType x) {
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
s.data = x;
s.next = Null;
if(Q.front == Null) {// 空队列插入第一个元素
Q.front = s;// 修改队头队尾元素
Q.rear = s;
} else {
Q.rear->next = s;
Q.rear = s;
}
}
// 出队
bool DeQueue(LinkQueue &Q,ElemType &x) {
if(Q.front == Null) {
return false;// 空队列
}else {
LinkNode *p = Q.front;
x = p->data;
Q.front = Q.front->next;
if(Q.rear == p) {// 如果你删除的是最后一个结点的话
Q.rear = Q.front = Null;// 需要修改队尾指针
}
free(p);
return true;
}
}